题目描述:给你一个有序数组 nums ,请你原地删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 len = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素
题解:
从题目中可以得知数组中的元素是有序的,所以数组中相同的元素必然是连续的。因为重复出现次数超过两次的元素只保留前两次,所以我们可以把数组的第一个元素和第三个元素进行比较,如果相同则跳过当前元素,如果不同,则把这个元素移动到指定位置。
这里可以定义两个变量,numsSize为原数组长度,len为新数组长度,新数组会在原数组的基础上进行删除,len初始值为0,每次循环将nums[i]和nums[len-2]进行比较,如果不相等跳过本次判断,如果相等则进入判断,把当前值nums[i]赋给nums[len],然后len++、i++,遍历下一个元素,重复以上操作。
需要注意的,len初始值为0,所以一开始nums[len-2]的值是随机值,如果一开始单纯只用
nums[i] != nums[len - 2]作为判断条件,可能会出现一些bug,为了避免这个bug,我们可以在一开始的时候加上len < 2进行判断,当len = 2时,就可以继续用nums[i] != nums[len - 2]作为判断条件。
完整代码:
#include <stdio.h>
/* 比较当前元素nums[i]与nums[len-2]的关系 */
int removeDuplicates(int* nums, int numsSize)
{
int len = 0; // 对新长度len进行初始化
int i = 0;
for (i = 0; i < numsSize; i++) {
/* 当前值与nums[len-2]不相等, 就是新的元素, 添加到结果中 */
if (len < 2 || nums[i] != nums[len - 2]) {
nums[len++] = nums[i];
}
}
return len; // 返回新长度值
}
int main()
{
int nums[] = {1,1,1,2,2,3,};
int numsSize = sizeof(nums)/sizeof(int);
int len = removeDuplicates(nums,numsSize);
printf("len = %d ",len);
int i = 0;
for(i = 0; i < len; i++)
{
printf("nums = %d",nums[i]);
}
printf(" ");
return 0;
}