27

力扣80——删除排序数组中的重复项 II

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU0NTk3NDMyMQ%3D%3D&%3Bmid=2247483933&%3Bidx=1&%3Bsn=b2c6991e75a8871852e6d5159507c0f4
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

原题

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

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

示例 1:

给定 nums = [1,1,1,2,2,3],

函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,1,2,3,3],

函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。

你不需要考虑数组中超出新长度后面的元素。

说明:

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

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

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

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

原题url:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/

解题

本题比较恶心的地方在于针对重复的数字,可以最多留2个,而并不是全部删除,因此在这点上需要注意。可以用一个专门的变量记录当前数字重复的次数,当重复次数大于2的时候则直接删除该数字,当不同后,再将该变量重置。

让我们看一下代码:

class Solution {
    public int removeDuplicates(int[] nums) {
        if (nums.length <= 1) {
            return nums.length;
        }

        int start = 1, current = 1;
        // 已经出现过的数字before,及其出现的次数
        int before = nums[0];
        int times = 1;
        while (current < nums.length) {
            // 相同并且超过2个,则直接跳过
            if (nums[current] == before && times == 2) {
                current++;
                continue;
            }

            // 相同但是不超过2个

                        // 如果和之前一个数相同,则增加times
            if (nums[current] == before) {
                times++;
            }
                        // 如果不相同,则重置times
                        else {
                times = 1;
            }

            // 赋值,即拷贝该数到合适的位置
            nums[start] = nums[current];
            before = nums[current];
            // 移动指针
            current++;
            start++;
        }

        return start;
    }
}

提交OK,执行用时: 1 ms ,内存消耗: 37.3 MB 。应该没什么问题了。

总结

以上就是这道题目我的解答过程了,不知道大家是否理解了。

这已经是第9篇刷题的文章了,都是 medium 难度,感觉 medium 难度的话,重点关注的是一些边界判断,思考是否严谨,至于算法,还是比较基础的。不知道大家感觉如何。

有兴趣的话可以访问我的博客或者关注我的公众号,说不定会有意外的惊喜。

https://death00.github.io/

公众号:健程之道

uUfQ7jq.jpg!web 点击此处留言


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK