力扣LeetCode #80 删除排序数组中的重复项II(RemoveDuplicates)

- 题目描述

给定一个增序排列数组 nums ,你需要在 原地 删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。

提示:
0 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 按递增顺序排列

来源:LeetCode

- 示例

  • 示例 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 。 你不需要考虑数组中超出新长度后面的元素。

- 思路分析

看了别人写的代码让我失去了写分析的欲望。觉得自己是笨比。

- JAVA实现

  • 我的憨包解法
class Solution {
    public int removeDuplicates(int[] nums) {
        //如果超过两个,就直接把后面一位数移到这一位即可。
        if(nums.length <= 2) return nums.length;
        int count = 1;
        int last = nums[0];
        int dist = 1;  //即当前数应该填入的位置
        for(int i=1; i<nums.length; i++) {
            //System.out.println("i="+i);
            if(nums[i] == last)  {   //等于上一个数
                if(count < 2) {
                    count++;  //如果目前只出现了一个数
                    nums[dist] = nums[i];
                    dist++;
                }
                else { //已经有两个数了
                    while((i+1)<nums.length && nums[i+1]==last) i++;
                    if(i+1 < nums.length) { //还有下一个数且这个nums[i+1]不等于last
                        nums[dist] = nums[i+1]; 
                        last = nums[dist];
                        count = 1;
                        dist++;
                        i++;                   
                    }
                    else break;     //没有下一个数了
                }
            }
            else {
                count = 1;
                nums[dist] = nums[i];
                dist++;
                last = nums[i];
            }
        }
        return dist;
    }
}
  • 更优解法:
class Solution {
    public int removeDuplicates(int[] nums) {
        int i = 0;
        for (int n : nums)
            if (i < 2 || n > nums[i-2])   //用n>nums[i-2]很巧妙地判断了是否已经有两个重复
                nums[i++] = n;
        return i;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值