目录
问题描述
给你一个 升序排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。考虑
nums
的唯一元素的数量为k
,你需要做以下事情确保你的题解可以被通过:
更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。返回
k
。示例 1:
输入:nums = [1,1,2] 输出:2, nums = [1,2,_] 解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4] 输出:5, nums = [0,1,2,3,4] 解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
核心代码解决
class Solution { public: int removeDuplicates(vector<int>& nums) { int n=nums.size(); if(n==0){ return 0; } int fast=1,slow=1; while(fast<n){ if(nums[fast]!=nums[fast-1]){ nums[slow]=nums[fast]; ++slow; } ++fast; } return slow; } };
代码思想
这是一种非常高效的解决方法,称为“快慢指针法”(Two Pointers Approach)。使用两个指针
fast
和slow
来遍历数组,将不重复的元素移动到数组的前部,同时记录不重复元素的个数。下面是这段代码的详细解释:
int n=nums.size();
:获取数组的长度。
if(n==0){ return 0; }
:如果数组为空,直接返回0,因为此时不存在唯一元素。
int fast=1,slow=1;
:初始化快指针和慢指针,均从索引1开始。
while(fast<n){ ... }
:循环遍历数组,快指针fast
从索引1开始。
if(nums[fast]!=nums[fast-1]){ ... }
:如果当前元素与前一个元素不相等,说明找到了一个不重复的元素。
nums[slow]=nums[fast];
:将这个不重复的元素移到慢指针的位置上,即覆盖掉之前重复的元素。
++slow;
:增加慢指针的位置,以便下一次找到不重复的元素时,可以将其放在正确的位置。
++fast;
:无论当前元素是否重复,快指针都需要前进。
return slow;
:循环结束后,slow
指针的位置即为数组中不重复元素的个数,将其作为结果返回。这段代码非常清晰、高效地实现了移除重复元素的操作,同时保持了数组的原始顺序。
时间复杂度和空间复杂度
这段代码使用了双指针法,时间复杂度为 O(n),其中 n 是数组的长度。空间复杂度为 O(1),因为您没有使用额外的数据结构来存储数据,只是在原数组上进行操作。
下面是对时间复杂度和空间复杂度的分析:
时间复杂度:代码中使用了两个指针
fast
和slow
分别遍历数组,每个指针最多遍历一次数组,因此时间复杂度为 O(n),其中 n 是数组的长度。空间复杂度:代码没有使用额外的数据结构来存储数据,只是在原数组上进行操作,因此空间复杂度为 O(1),即常数级别。
class Solution { public: int removeDuplicates(vector<int>& nums) { int n=nums.size(); if(n==0){ return 0; } int uniquetrue=1; // 唯一元素的数量,初始为1 for(int i=1;i<nums.size();i++){ if(nums[i]!=nums[i-1]){ nums[uniquetrue]=nums[i];// 将唯一元素移到正确位置 uniquetrue++; } } return uniquetrue;// 返回唯一元素的数量 } };
这段代码是一个C++的解法,用于在升序排列的数组中移除重复的元素,并返回去重后数组的长度。
以下是对代码的解释:
int removeDuplicates(vector<int>& nums)
:这是您定义的一个名为removeDuplicates
的函数,它接受一个整数数组nums
的引用作为参数。
int n=nums.size();
:获取数组的长度。
if(n==0){ return 0; }
:如果数组为空,直接返回0,因为此时不存在唯一元素。
int uniquetrue=1;
:在非空数组的情况下,初始化一个变量uniquetrue
,表示唯一元素的数量。这里初始值为1,因为数组中的第一个元素肯定是唯一的。
for(int i=1;i<nums.size();i++)
:然后,您使用一个循环遍历数组,从索引1开始,因为索引0的元素已经被视为唯一元素。
if(nums[i]!=nums[i-1])
:对于每个索引i
,检查当前元素是否与前一个元素不相等,以确定是否找到了一个不重复的元素。
nums[uniquetrue]=nums[i];
:如果当前元素不重复,将其移到唯一元素的位置(uniquetrue
索引处),以保持数组的相对顺序。
uniquetrue++;
:递增uniquetrue
,以记录唯一元素的数量增加了。
return uniquetrue;
:循环结束后,uniquetrue
的值即为数组中唯一元素的个数。将其作为结果返回。