赞
踩
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
写说一下自己最开始的思路,可能是以前嵌入式硬件编程总用标志位flag习惯了,思来想去,没想到别的,居然还是用了设置一个计数cnt和flag标志位。非常不出意外的,最后运行成功了18个例子之后,失败了,
int removeDuplicates(int* nums, int numsSize){ int fast = 0,slow = 0; int cnt = 0,flag = 0; for(int i = 0;i < numsSize;i++) { if(nums[fast] == nums[slow]) { cnt++; flag = 1; if(cnt >= 3) { flag = 0; cnt = 0; } } if(nums[fast] != nums[slow] || (flag == 1 && nums[fast] == nums[slow]) ) { int temp = nums[fast]; nums[fast] = nums[slow]; nums[slow++] = temp; } fast++; } return slow; }


已经不知道问题出在哪儿,有点怪异,这个3,按理说不应该没有啊???
具体地,我们定义两个指针 slow 和 fast 分别为慢指针和快指针,其中慢指针表示处理出的数组的长度,快指针表示已经检查过的数组的长度,即 nums[fast] 表示待检查的第一个元素,nums[slow−1] 为上一个应该被保留的元素所移动到的指定位置。
因为本题要求相同元素最多出现两次而非一次,所以我们需要检查上上个应该被保留的元素 nums[slow−2]是否和当前待检查元素 nums[fast]相同。当且仅当 nums[slow−2]=nums[fast]时,当前待检查元素 nums[fast]不应该被保留(因为此时必然有 nums[slow−2]=nums[slow−1]=nums[fast])。最后,slow 即为处理好的数组的长度。
特别地,数组的前两个数必然可以被保留,因此对于长度不超过 222 的数组,我们无需进行任何处理,对于长度超过 222 的数组,我们直接将双指针的初始值设为 222 即可。
int removeDuplicates(int* nums, int numsSize){
int index = 0;
for(int i = 0;i < numsSize;i++)
{
if(nums[i] != nums[index])
nums[++index] = nums[i];
}
return index+1;
}
已经做了好几道这个删除题了,为了让解法更具有一般性,我们将原问题的「保留 2 位」修改为「保留 k 位」。
对于此类问题,我们应该进行如下考虑:
这是一种针对「数据有序,相同元素保留 k 位」问题更加本质的解法,该解法是从性质出发提炼的,利用了「数组有序 & 保留逻辑」两大主要性质。
class Solution { public int removeDuplicates(int[] nums) { return process(nums, 2); } int process(int[] nums, int k) { int u = 0; for (int x : nums) { if (u < k || nums[u - k] != x) nums[u++] = x; } return u; } } 作者:宫水三叶 链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/solutions/702970/gong-shui-san-xie-guan-yu-shan-chu-you-x-glnq/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。