6. <tag-数组和双指针(快慢针)>-lt.26- 删除有序数组中的重复项+lt.283-移动零 2.7
lt.26 删除数组中的重复元素
[案例需求]
[思路分析]
- 本道题是典型的使用快慢指针的题目;
- 首先给出的数组是有序的, 并且是原地对数组进行操作的, 所以我们必须要考虑用双指针解题, 而且这两个指针能够在一定程度上分别指向需要原地交换的两个数, 不是说删除吗, 为什么还会交换呢? 因为数组在底层并不是真正的删除一个元素, 而只是忽略掉这个元素的索引, 所以我们通过交换把需要访问的非重复元素放在前半段, "删除"后的元素放在后面, 只访问前半段;
- 再仔细读题目, 发现我们需要返回对数组去重后的非重复数组, 所以我们能够想到留一个指针去指示每次交换后的非重复数组, 而把另一个指针用来遍历整个数组;
[代码实现]
class Solution {
public int removeDuplicates(int[] nums) {
//有序数组, 理应考虑到双指针, 至于何种双指针, 细读题目
// 定义左右指针L,R. L始终指向非重复的数组最后一位, R是遍历原数组,
// 发现与L的元素不同, 立即移动L指针, 并交换L,R对应的元素
// L 与 R元素相同, 则R继续向后移动一位
int L = 0;
int R = 1;
if(nums.length < 1) return 0;
while(R < nums.length){
if(nums[L] != nums[R]){
L++;
nums[L] = nums[R];
}
R++;
}
return L+1;
}
}
lt. 283 移动零
[案例需求]
[思路分析]
- 为什么会想到用双指针? 一是他要求原地逆转(肯定要用到数组中两个数之间的交换), 我们肯定会需要两个游标(或者说指针)来指示每次需要交换的两个数, 二是我们从题目可知, 数组前一部分要求是不为0, 所以我们肯定需要指针来指示每次遍历时, 数组不为0的末尾的位置;
- 具体思路如下:
1. 定义两个指针, 快慢指针, slow用于标记每次遍历之后, 数组中不为0部分的最后一个数, 初值应设为 -1, 为什么 -1? 因为我们每次交换两个数时, 我们需要先移动 slow指针, 这个时候slow指针才会指向0哦;
2. 快指针 fast, 用于遍历整个数组, 初值为0,
- 每当遇到不为0的数时, 便要在移动一位慢指针后, 与快指针交换.
- 每当遇到为0的数, 变直接后移一位即可;
[代码实现]
class Solution {
public void moveZeroes(int[] nums) {
//移动0 , 原地移动, 快慢指针
int slow = -1;
int fast = 0;
int temp = 0;
while(fast < nums.length){
if(nums[fast] != 0){
slow++;
temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
}
fast++;
}
}
}
[思路二, 一次遍历, 不使用交换方法]
- 还是用双指针, 因为数组中不为0的数的个数肯定是要小于为0的数的个数的, 而题目只是要求我们把0放在后面, 所以我们可以先用fast遍历一次数组, 然后用slow从0-> slow, 用fast遇到的不为0的数去覆盖0->slow的所有数
- 这样的话, fast一趟遍历下来, 不为0的数都集中到了数组的前部分, 也就是从0–>slow的区间内, 然后再把slow–> nums.length的数置为0即可,
- 相比于思路一, 不用交换0和非0元素, 降低了时间复杂度.
class Solution {
public void moveZeroes(int[] nums) {
//fast先循环一趟, 把不为0的数全部赋值给slow
int slow = 0;
int len = nums.length;
if(len < 2)return;
for(int fast = 0; fast < len; fast++){
if(nums[fast] != 0){
nums[slow] = nums[fast];
++slow;
}
}
for(int i = slow; i < len; i++){
nums[i] = 0;
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)