Leetcode学习之 80.删除有序数组中的重复项 II

在这里插入图片描述
执行速度0ms,题目重点是原地删除以及只可以使用额外的O(1)空间。所以按照平常的新旧数组复制是不可行的。因此想到了利用双指针(fast,slow)利用元素交换下标的或者覆盖的方式进行删除。
双指针过程如下图所示:
图中实例: nums = 0 0 1 1 1 1 2 3 3
在这里插入图片描述

  1. 首先找出第一个出现符合重复条件的元素,也就是实例下标4的元素1
  • 利用count进行计数,当temp记录当前数,fast进行遍历后续的数
  • 当fast遇到与temp不相同的元素时,更新temp为新的元素,count置位0
  • fast继续前移,直到找到属于重复项元素的第一个下标
for (fast = 0; fast < nums.length; fast++) {
            if (nums[fast] == temp) {
                count++;
            }
            //如果大于2,则break跳出循环
            if (count > 2) {
                break;
            }
            //如果没大于2,且count=0,则继续
            if (nums[fast] != temp) {
                temp= nums[fast];
                count = 1;
            }
        }
  1. 通过下标4的元素开始执行我们的置换,主要是以下几步:
  • 开始置换,只要fast对应的位置和slow对应的 前2个位置(刚好符合最极限的允许2个相同元素的条件),即slow -2 不相同,
    则可以认为fast所指的位置是符合要求的数字,
  • 把fast所指数插入到slow所指的位置中,slow++(后移)
  • 因为slow至少从nums第三个元素起,所以不会出现 slow-2越界
  • 其他情况则fast后移
for(fast=slow+1;fast<nums.length;fast++){
     if(nums[fast] != nums[slow-2]){
          nums[slow++] = nums[fast];
     }
}

最后只需要返回slow的下标位置,就是题目所需要的删除后的数组长度啦

全部代码:

public int removeDuplicates(int[] nums) {
        int slow, fast;
        int count = 0;
        int temp = nums[0];
        //快指针先走
        for (fast = 0; fast < nums.length; fast++) {
            if (nums[fast] == temp) {
                count++;
            }
            //如果大于2,则break跳出循环
            if (count > 2) {
                break;
            }
            //如果没大于2,且count=0,则继续
            if (nums[fast] != temp) {
                temp= nums[fast];
                count = 1;
            }
        }
        //slow指向当前fast指针所在得位置,然后fast指针继续向前
        slow = fast;
        //开始置换
        /**
         *  开始置换,只要fast对应的位置和slow对应的 前2个位置(因为一个元素可以重复两次),
         *  1. 即slow -2 不相同,则可以认为fast所指的位置是符合要求的数字,
         *  2. 插入到slow所指的位置中,slow++(后移)
         *  3. 因为slow至少从nums第三个元素起,所以不会出现 slow-2越界
         */
        for(fast=slow+1;fast<nums.length;fast++){
            if(nums[fast] != nums[slow-2]){
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值