1、题目:
对给定的有序数组 nums 删除重复元素,在删除重复元素之后,每个元素只出现一次,并返回新的长度,上述操作必须通过原地修改数组的方法,使用 O(1) 的空间复杂度完成。
2、分析特点:
- 题目要求:原地修改、
有序数组
- 原地+删除 ==>
结果数组一定比原数组的长度更短
,并且,我们可以把结果数组直接写在原数组上
。 - 有序数组 ==> 当前元素和前一个元素是相等的时候,则不需要收集,
我们需要收集的元素,是那些不会等于前一个元素的,充分利用有序的特点
,继续往前遍历,只要不等于前一个元素,就可以收集起来,等于了就放弃,比如 2 3 3,第一个 3 作为当前元素的时候,和前一个元素不相等,可以收集起来,到了第二个 3 和前一个元素相等了,放弃收集。
3、特点:
有序数组,剔除掉相等的,拿当前位置的元素去和前一个元素比较 ,即if (nums[fast] != nums[fast - 1]); 并且 0 位置的元素早就进入结果集,需要看后面的元素是否进结果,则定义的两个指针开始判断收集的起点下标从1开始。
定义两个指针 fast 和 slow 分别为快指针和慢指针,
快指针表示遍历原数组到达的下标位置,慢指针表示结果数组的下标位置,即下一个不同元素要填入的下标位置,初始时两个指针都指向下标 1。
快指针的范围是从 1 到 最后一个元素位置;
慢指针是从 1 开始不断根据快指针满足了条件就加入收集结果(前提,0位置的元素早就进入了结果,需要看后面的元素是否进结果);
4、代码:
public int removeDuplicates(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
int slow = 1;
for(int fast = 1; fast < n; fast++){
if (nums[fast] != nums[fast - 1]) {
nums[slow] = nums[fast];
++slow;
}
}
return slow;
}
5、复杂度分析:
- 时间复杂度:O(n),其中 n 是数组的长度。快指针和慢指针最多各移动 n 次。
- 空间复杂度:O(1)。只需要使用常数的额外空间。
6、总结:
有序数组,剔除掉相等的,拿当前位置的元素去和前一个元素比较,即if (nums[fast] != nums[fast - 1]); 并且 0 位置的元素早就进入结果集,需要看后面的元素是否进结果,则定义的两个指针开始判断收集的起点下标从1开始。
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!