539,双指针解删除有序数组中的重复项

Years may wrinkle the skin, but to give up enthusiasm wrinkles the soul. 

岁月留痕,只及肌肤;激情不再,皱起心灵。

问题描述

给你一个有序数组nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。

 

不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。

 

示例 1:

输入:nums = [1,1,2]

输出:2, nums = [1,2]

解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]

输出:5, nums = [0,1,2,3,4]

解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

 

提示:

  • 0 <= nums.length <= 3 * 10^4

  • -10^4 <= nums[i] <= 10^4

  • nums 已按升序排列

 

双指针解决

因为数组是排序的,只要是相同的肯定是挨着的,我们只需要遍历所有数组,然后前后两两比较,如果有相同的就把后面的给删除。

 

使用两个指针,右指针始终往右移动,

  • 如果右指针指向的值等于左指针指向的值,左指针不动。

  • 如果右指针指向的值不等于左指针指向的值,那么左指针往右移一步,然后再把右指针指向的值赋给左指针。

 

具体看下视频

 

来看下代码

 1//双指针解决
2public int removeDuplicates(int[] A) {
3    //边界条件判断
4    if (A == null || A.length == 0)
5        return 0;
6    int left = 0;
7    for (int right = 1; right < A.length; right++)
8        //如果左指针和右指针指向的值一样,说明有重复的,
9        //这个时候,左指针不动,右指针继续往右移。如果他俩
10        //指向的值不一样就把右指针指向的值往前挪
11        if (A[left] != A[right])
12            A[++left] = A[right];
13    return ++left;
14}

或者还可以换一种解法,其实原理都是一样的。

 1public int removeDuplicates(int[] A) {
2    int count = 0;//重复的数字个数
3    for (int right = 1; right < A.length; right++) {
4        if (A[right] == A[right - 1]) {
5            //如果有重复的,count要加1
6            count++;
7        } else {
8            //如果没有重复,后面的就往前挪
9            A[right - count] = A[right];
10        }
11    }
12    //数组的长度减去重复的个数
13    return A.length - count;
14}
上一篇:2011 执行操作后的变量值


下一篇:IT十年人生过客-帝都(梦想之城)