题目:
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length =5
, 并且原数组的前五个元素被修改为1, 1, 2, 2,
3 。 你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,1,2,3,3], 函数应返回新长度 length =7
, 并且原数组的前五个元素被修改为0
, 0, 1, 1, 2, 3, 3 。 你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); }
思路:直接看了网上大神的代码,原文:https://blog.csdn.net/spring_3_shine/article/details/80006147
以下的代码使用了两个指针,一个len2,一个i。每次将nums[i]于nums[len2-1]进行比较,若两者不相等则在原地将自己本身的值赋给自己;若两者相等,则使用cnt记录相等的数字的个数,开始时cnt的值为1,当第一次出现前后两个值相等时cnt加1,当再次出现相等的值时,cnt变为3,此时len2不动,i指针向前知道找到不同的值为止,此时将i的值赋给len2.
代码:
class Solution {
public int removeDuplicates(int[] nums) {
int repeat=2;
if(nums.length<=repeat)
return nums.length;
int len2=1;
int cnt=1;
for(int i=1;i<nums.length;i++){
if(nums[i]!=nums[len2-1]){
cnt=1;
nums[len2++]=nums[i];
} else{
cnt++;
if(cnt>repeat){
continue;
} else{
nums[len2++]=nums[i];
}
}
}
return len2;
}
}
最快的代码:
写的代码好少。以下代码是依次遍历所给数组中的每一个元素。对于前两个元素不需要检查,因为即使重复的话也是符合要求的,所以直接给自己赋值;对于之后的元素,需要判断和之前两个元素是否相等。由于整个数组是已经排序好了的,所以直接用大于判断。若不相等直接赋值,若想等,,跳过就可以了,即指针i不懂,数组元素的指针继续往后走,知道遇到一个不相等的元素。和上面的思路差不多,但写的简介。
class Solution {
public int removeDuplicates(int[] nums) {
int i = 0;
for (int num : nums) {
if (i < 2 || num > nums[i - 2]) {
nums[i++] = num;
}
}
return i;
}
}
提交最多的代码:
这和最快的代码是一样的
class Solution {
public int removeDuplicates(int[] nums) {
/**
for e in nums:
if i < 2 or e != nums[i-2]:
nums[i] = e
i += 1
return i
*/
if(nums == null || nums.length == 0 ){
return 0;
}
if(nums.length ==1 ){
return 1;
}
int k =0;
for(int i=0; i<nums.length; i++){
if(k<2 || nums[i]!=nums[k-2] ){
nums[k++] = nums[i];
}
}
return k ;
}
}