题目
题目来源:LeetCode 80
https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/?envType=study-plan-v2&envId=top-interview-150
给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
输入: nums = [1,1,1,2,2,3]
输出: 5, nums = [1,1,2,2,3]
解释: 函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3。 不需要考虑数组中超出新长度后面的元素。
示例 2:
输入: nums = [0,0,1,1,1,1,2,3,3]
输出: 7, nums = [0,0,1,1,2,3,3]
解释: 函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3。不需要考虑数组中超出新长度后面的元素。
通解
将原问题的2位改成k位
对于这类问题应该进行如下考虑:
- 对于前k个数字可以直接保留
- 对于后面的任意数字,与当前写入位置前面的第k个元素进行比较,不相同就保留
举个例子:
k=2
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
元素 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 3 | 3 | 3 |
1、直接保留前面k个元素,此时第一个元素nums[0]为idx
2、从nums[2]开始与前面的idx比(idx是它前面第2个元素),与idx相同,于是就往后找到与idx不同的元素,继续比较
int removeDuplicates(int* nums, int numsSize){
int idx = 0; //第一个元素作为idx
if(numsSize < 2)
return 1;
int count = 2; //相当于慢指针,记录删除重复元素后数组中元素的个数
for(int i = 2; i < numsSize; i++){ //从nums[2]开始与idx进行比较,i相当于快指针
if(nums[i] != nums[idx]){ //不相等
nums[count++] = nums[i]; //赋值,慢指针指向下一个元素
idx++; //idx指向下一个元素
}
//相等就跳过此次循环
//往后找到不相等的元素
}
return count;
}