leetcode看了三叶大佬的讲解,自己再总结下,此方法 适用于 数据排序有序,并且要求里面相同元素最多只能保留几个的时候 的求法,如:
分析:
因为要求每个元素最多保留2个相同的,所以可以直接先保留前两个元素,然后对后面的元素进行比较,如果第三个元素仍与第二个元素相同,则接着往后面走,继续判断,直到与前面两个元素不同保留,然后将第三个元素赋值为此数值,以此类推。
如:[ 0,1,1,1,2,2,2,2,3,4,5,5]
首先用一个变量来记录插入的位置,int idx=0;
1、idx = 0,此时数组为:[]
2、保留前两位,数组为:[0,1]
3、然后进行判断第三个元素是否跟第二个元素(1)相等,如果相等则跳过,直到不等(1)进行保留,如例题所示第三位为1,则跳过,直到第五位为2不等于1,进行保留。
那么此阶段判断就需要满足上面分析的两个加黑部分。
①、先保留前两个元素
这里因为要求是2位,所以这里定义一个变量 k = 2,在于限制后面每个元素只能出现k(2)次,因此就要对 idx 进行限制,因为 idx 初始值设为0,所以 条件一:idx <k。保留前两位元素后,此时 idx=2
②、直到与前面两个元素不同保留
由于是有序元素,所以后面的元素就要先给前面元素进行比较,也就是与当前位置的前面 k
(2)个元素比较,不同则保留,例如此例,第三个元素为1,则1要与第一个元素0比较,不同,则保留,由于此时idx =2,要保留第三个元素,则nums[idx++] = x;接着第四个元素1,与第二个元素1比较,相同则不保留,此时idx =3,接着第五个元素2,与第三个元素1比较,不同则保留,此时idx =3,要保留第四个元素,则 nums[idx ++] = x。 依此类推,就能保证每个元素最多出现2次。因此 条件二为:nums[idx -k] != x
由于上面两个条件是先后且不是都必须同时成立,所以 条件用 ||
由此 写出代码如下 :
for(int x:nums){
if(idx <=k || nums[idx -k] != x) nums[idx++] = x;
}
最终可以写为如下:
class Solution {
public int removeDuplicates(int[] nums) {
return pross(nums,2);
}
int pross(int[] nums,int k){ //k为重复元素最多保留几位,此题k=2
int idx =0;
for(int x: nums){
if(idx <k || nums[idx -k] !=x){
nums[idx++] = x;
}
}
return idx;
}
}