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}
标签:right,指向,nums,int,数组,539,指针 来源: https://blog.51cto.com/u_4774266/2898152