【初级算法】删除排序数组中的重复项
题目:
一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,必须在原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。
思路:
首先还是最基础的解答思路,数组已经排序,则重复值都会连在一起,故按顺序遍历数组,如果当前元素与下一元素相同,则删除下一节点,数组整体向前移动,否则继续遍历
解答:
class Solution { public int removeDuplicates(int[] nums) { int i = 0; int end = nums.length - 1; while (i < end) { if (nums[i] == nums[i+1]) { for (int j = i+1; j < end; j++) { nums[j] = nums[j+1]; } end--; } else { i++; } } return end + 1; } }
结果与反思:
时间与空间都有极大浪费,需要考虑优化方案。
首先大部分的时间都浪费在数组删除元素上,考虑到题目要求原地修改,且不关注去重长度后的数组部分内容,可以不对数组进行前移调整,只将正确的值放在正确的位置最后通过裁剪达到效果。
优化思路:
使用双指针结构。
右指针始终往右移动,起到遍历功能,查到正确的值。
左指针默认不移动,与右指针值不相同时向右移动,代表去重后元素的正确位置。
如果右指针指向的值不等于左指针指向的值,那么左指针往右移一步,然后再把右指针指向的值赋给左指针;否则右指针继续右移,直到遍历结束。
优化答案:
class Solution { public int removeDuplicates(int[] nums) { int left = 0; for (int right=1; right) { if (nums[left] != nums[right]) { nums[++left] = nums[right]; } } return left + 1; } }