Vison's Blog
所有文章
文章总览
编辑器
Publications
About Me
Search
目录
#toc-container
下载Markdown文件
【4.6】LeetCode每日一题· 删除有序数组中的重复项 II
2021年04月06日 10时29分
标签:
LeetCode
双指针
## 题目描述 给你一个有序数组`nums`,请你**[原地](https://baike.baidu.com/item/%E5%8E%9F%E5%9C%B0%E7%AE%97%E6%B3%95)**删除重复出现的元素,使每个元素**最多出现两次**,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在[原地](https://baike.baidu.com/item/%E5%8E%9F%E5%9C%B0%E7%AE%97%E6%B3%95)**修改输入数组**并在使用 O(1) 额外空间的条件下完成。 #### 说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以**「引用」**方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以想象内部操作如下: ``` // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); } ``` #### 示例1 ``` 输入:nums = [1,1,1,2,2,3] 输出:5, nums = [1,1,2,2,3] 解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。 ``` #### 示例2 ``` 输入:nums = [0,0,1,1,1,1,2,3,3] 输出:7, nums = [0,0,1,1,2,3,3] 解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。 ``` #### 提示 ``` 1 <= nums.length <= 3 * 10^4 -10^4 <= nums[i] <= 10^4 nums 已按升序排列 ``` #### 来源 > 来源:力扣(LeetCode) > 链接:[题目链接](https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii "题目链接") ## 解题思路 双指针,设置两个指针`i`和`j`,其中`i`不停地向后扫描数组,`j`表示需要将`i`位置的值赋值给`j`位置上的元素。另外设置一个变量`cnt`记录当前扫描的数字的个数,`curr`表示当前扫描到的前一个数字。 那么如果当前扫描到的数字和前一个数字相同,即`nums[i] == curr`,则将`cnt`加一,否则重置`cnt`和`curr`,然后将当前位置的值赋值给`j`位置的值。 接着判断`cnt`是否大于2。如果是,则说明当前`j`位置的元素应该被后面元素覆盖,因此停止`j`的自增;否则,将`j`自增1. 最后,将`i`自增1。重复上述操作直到遍历完整个数组为止。 ### 代码 ```cpp class Solution { public: int removeDuplicates(vector
& nums) { int j = 0, cnt = 0, curr = nums[0]; // cnt记录当前数字的个数,curr记录当前数字的值 for(int i = 0; i < nums.size(); ++i){ if(nums[i] == curr){ ++cnt; }else{ curr = nums[i]; cnt = 1; } nums[j] = nums[i]; if(cnt <= 2){ ++j; } } return j; } }; ``` ## 用时和内存 > 执行用时:4 ms,在所有 C++提交中击败了90.88%的用户 > 内存消耗:10.6 MB,在所有 C++提交中击败了67.36%的用户
所有评论
暂无评论
新增评论
评论
邮箱
邮箱仅作验证使用
图形验证码
邮箱验证码
发送验证码
发表评论
所有评论
暂无评论