一. 题目链接
二. 解题思路
-
检查特殊情况:如果数组长度为0,即数组为空,则直接返回0,因为没有元素要处理。
-
初始化两个指针:
dest
指针用来记录新数组中最后一个不重复元素的位置。由于数组至少有一个元素,dest
初始指向第一个元素的位置,即索引0。cur
指针用来遍历数组,从数组的第二个元素开始,即索引1。
-
遍历和去重:
- 遍历整个数组,检查
cur
指向的当前元素。 - 如果当前元素(
nums[cur]
)与dest
指向的元素(nums[dest]
)不相同,这意味着发现了一个新的不重复元素。 - 将这个新的不重复元素复制到
dest + 1
的位置,这是因为我们要在新数组的末尾添加这个元素,并且移动dest
和cur
指针。 - 如果
nums[cur]
与nums[dest]
相同,则仅将cur
指针向前移动,跳过这个重复的元素。
- 遍历整个数组,检查
-
返回新数组的长度:
- 在完成遍历之后,
dest
指针的位置加1(因为索引是从0开始的)即为新数组的长度。
- 在完成遍历之后,
三. 动画解析
四. 代码解析
// 函数定义:移除有序数组中的重复元素,并返回新的数组长度
int removeDuplicates(int* nums, int numsSize)
{
// 如果数组为空,则直接返回长度为0
if(numsSize == 0)
{
return 0;
}
// dest指针用于记录最后一个不重复元素的位置
int dest = 0;
// cur指针用于遍历数组中的每一个元素
int cur = 1;
// 初始化,将第一个元素视为不重复元素
nums[dest] = nums[0];
// 遍历数组中除了第一个元素之外的所有元素
while(cur < numsSize)
{
// 当前元素与dest位置的元素不相同,说明发现了新的不重复元素
if(nums[cur] != nums[dest])
{
// 将这个新的不重复元素移动到dest+1的位置
nums[++dest] = nums[cur++];
}
else
{
// 如果当前元素与dest位置的元素相同,跳过这个重复元素
cur++;
}
}
// 返回新的数组长度,因为dest是从0开始的索引,所以要加1
return dest+1;
}
五. 题目链接
六. 解题思路
-
初始化变量:
Numsize
存储数组的大小。cur
是一个指针变量,开始时指向数组的第二个元素,因为我们将比较当前元素与之前的元素。dest
是一个指针变量,表示新数组无重复元素的最后一个元素的索引,开始时指向第一个元素,假设它是唯一的。flag
用来记录与当前元素值相同的元素出现的次数,因为每个元素最多允许出现两次,所以当遇到第一个元素时初始化为1。
-
特殊情况处理:如果数组的大小不超过2,那么所有元素自然都满足条件(因为每个元素最多允许出现两次),直接返回数组的大小。
-
遍历数组:使用
cur
指针从索引1开始遍历数组,与dest
指针所指的元素进行比较。 -
复制或跳过元素:
- 如果
cur
指向的元素与dest
指向的元素相同,且flag
小于2,则将cur
指向的元素复制到dest+1
的位置,并递增dest
和cur
,同时flag
也递增,因为我们遇到了一个重复的元素。 - 如果
cur
指向的元素与dest
指向的元素相同,但flag
大于等于2,这意味着当前元素已经至少重复了两次,所以不将它复制到新数组中,只递增cur
。 - 如果
cur
指向的元素与dest
指向的元素不同,说明遇到了新的元素,将cur
指向的元素复制到dest+1
的位置,并递增dest
和cur
,同时将flag
重置为1。
- 如果
-
返回新的数组长度:遍历结束后,
dest+1
就是新的数组长度,因为dest
指向新数组中最后一个元素的索引。
七. 动画解析
暂无
八. 代码解析
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int Numsize = nums.size();
int cur = 1;
int dest = 0;//默认第一个是独一无二的
int flag = 1;//第二个元素至多可以重复一次,所以初始化flag为1,表示第一个元素已经出现过一次
if (nums.size() <= 2)
{
return nums.size(); // 如果数组大小不超过2,则不需要任何操作
}
while (cur < Numsize)
{
if (nums[cur] == nums[dest] && flag < 2)
{
// 如果当前元素与前一个相同,但还没有重复超过一次,那么也添加到数组中
nums[++dest] = nums[cur];
cur++;
flag++;
}
else if (nums[cur] == nums[dest] && flag >= 2)
{
//这种情况就不符合题目条件了
cur++;
}
else
{
// 如果当前元素(cur)与前一个(dest)不同,那么它可以被添加到dest+1的位置中
nums[++dest] = nums[cur];
cur++;
flag = 1;
}
}
return dest + 1;// 数组的新长度是最后一个元素的索引 + 1
}
};
注意:
这些步骤可能忘记
if (nums.size() <= 2) { return nums.size(); // 如果数组大小不超过2,则不需要任何操作 }
虽然不写不会影响代码的正确性,且对于较大的数组,这个检查对于整体性能的影响是微不足道的。但是对于小数组来说,代码将继续进行不必要的迭代,影响了性能。