前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【LeetCode每日一题】80. 删除有序数组中的重复项 II

【LeetCode每日一题】80. 删除有序数组中的重复项 II

作者头像
公众号guangcity
发布2021-04-22 14:27:24
2970
发布2021-04-22 14:27:24
举报
文章被收录于专栏:光城(guangcity)

【LeetCode每日一题】80. 删除有序数组中的重复项 II

今日题目80题,每日一题微信交流群可以点击右下角:合作转载->联系我,拉你入群。

题目:

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝

代码语言:javascript
复制
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。

代码语言:javascript
复制
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

示例 1:

代码语言:javascript
复制
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。

示例 2:

代码语言:javascript
复制
输入: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 。 不需要考虑数组中超出新长度后面的元素。

题解:

直接模拟,题目中要求采用O(1)空间,那么我们考虑使用原有的nums数组作为空间存储对象。

模拟过程中设置两个变量:i与j。

  • i表示每次遍历的元素下标
  • j表示目标结果数组的元素下标

例如:[1,1,1,1,2,2],第一次循环结束后i指向的是当前重复元素最后一个位置,也就是index=3,而j指向的是index=2。

代码语言:javascript
复制
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n = nums.size();
        if (n<=2) return n;

        int i = 0, j = 0;
        
        // j每循环一次,指向一个新的元素在nums目标位置
        while (i < n) {
            int prev = nums[i], count = 1;
            while (i+1 < n && nums[i+1]==prev) {
                if (count<=2) {
                    nums[j++] = nums[i];
                }
                count++;
                i++;
            }
            
            if (count <= 2) {  // 当前元素与下一个元素不一样 直接拷贝 并前进
                nums[j++] = nums[i++]; // 实际分为两种:第一种是 [1,2],第二种:[1,1,2]
            } else { // 元素超过2个 前面while前进过程中 已经做完拷贝 直接前进
                i++;
            }
        }
        return j;
    }
};

上述方法写的有点麻烦了,我们可以进行优化为:

代码语言:javascript
复制
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int j = 0; 
        for (auto x : nums) {
            if (j < 2 || x != nums[j-2]) {
                nums[j++] = x;
            }
        }
        return j;
    }
};

那么这道题改为最多出现k次,可以将上述函数抽出来。

代码语言:javascript
复制
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        return get(nums, 2);
    }

    int get(vector<int>& nums,int k) {
        int j = 0; 
        for (auto x : nums) {
            if (j < k || x != nums[j-k]) {
                nums[j++] = x;
            }
        }
        return j;
    }    
};

本节完~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【LeetCode每日一题】80. 删除有序数组中的重复项 II
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档