26. 删除有序数组中的重复项
26. 删除有序数组中的重复项
分析
- 非严格递增排列 的数组,意思是数组递增,但是存在重复元素
- 请你原地删除重复出现的元素,就是用覆盖的方式
基本上就确定了是用双指针,我们在 27. 移除元素 中就学过,只要是要求在原数组上移除元素的,几乎都是用双指针。
解题
需要注意,跟 27. 移除元素 相比,我们增加一步,就是要用一个变量记录上一次快指针遍历的元素,然后在后期通过快指针遍历整个数组的时候,碰到不同的值就更新这个值,而且题目是删除重复项,因此数组的第一个元素是不会被移除的,因为此时还没有任何对比,因此,快慢指针从第二个元素(索引为 1)开始遍历整个数组。
public int removeDuplicates(int[] nums) {
// 用一个变量来保存快指针上一次遍历的元素
int lastEle=nums[0];
// 第一个元素一定不会被剔除,因此我们从索引为1的元素开始遍历
int slow=1,fast=1;
for(;fast<nums.length;fast++){
if(nums[fast]!=lastEle){
nums[slow]=nums[fast];
slow++;
// 更新 lastEle
lastEle = nums[fast];
}
}
return slow;
}
还可以简化,即 lastEle,其实就等于上一个保存的变量,也就是上一次对比之后慢指针指向的值,所以,我们可以省略这个变量,用 slow 来表示,不过我们需要注意两个定义的区别:
- 上一次对比的结果保存的位置
- 下一次目标元素需要插入的位置
在上面的解法中,我们这样初始化int slow=1,fast=1;
实际上就是让 slow 指针指向 下一次目标元素需要插入的位置 。
现在我们想省略 lastEle,就需要让 slow 指向上一次对比的结果保存的位置。
public int removeDuplicates(int[] nums) {
// 因为是去除重复元素,所以第一个元素不需要判断,直接进入结果中,所以fast直接从1开始
// slow从0开始,此时,slow指向的是上一次对比的结果保存的位置
int slow=0,fast=1;
for(;fast<nums.length;fast++){
// 直接跟上一次上一次对比的结果进行对比,确定是否重复
if(nums[fast]!=nums[slow]){
slow++;
nums[slow]=nums[fast];
}
}
return slow+1;
}
相关题
27. 移除元素
283. 移动零
844. 比较含退格的字符串
977. 有序数组的平方
滑动窗口
209. 长度最小的子数组
904. 水果成篮