【LeetCode-java】复习专题(2):双指针(2):移除元素

今天复习专题写的是双指针的26.删除排序数组中的重复项27.移除元素

26 删除排序数组中的重复项 Remove Duplicates From Sorted Array

  • 难度:简单

  • 想写这个主要是因为这是我在LeetCode上做的第一个题(还真不是Two Sum= =),当时其实做的有点懵,不过后来就好很多啦。

  • 题目:给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组 并在使用 O ( 1 ) \mathcal{O}(1) O(1) 额外空间的条件下完成。

  • 这里要求的是在原地修改数组,所以就不可以复制一个之后再做。

  • 总体的思路就是维护两个指针,一个快指针遍历数组查看是否有重复,另一个慢指针负责修改数组。

  • 这个题实际上比27题多了一些弯将在下面讲述:

  • 1.首先,for循环是需要从i=1(右指针)开始遍历的,因为nums[0]总是要保留的。

  • 2.然后就是j(左指针)当然是从0开始遍历的,因为至少要和第一个元素做对比。只有当nums[i] != nums[j]的时候才会移动。注意这里是先移动再赋值。所以是++j

  • 3.最后,返回值是j+1,因为如果是j则实际上最后一个并没有被包含进去。之前的保证的是最后一个元素没有重复,但是如果只是j则不包含这个最后一个元素,而这个元素就在nums[j+1]的地方。

  • 这个题虽然简单,但是很多细节的地方也要注意。

class Solution {
    public int removeDuplicates(int[] nums) {
        int j=0;
        for(int i=1;i<nums.length;i++){ //i=1是因为第一个总是要保留的
            if(nums[i]!=nums[j]){
                nums[++j] = nums[i];//++j也是因为第一个要保留,所以先加再换
            }
        }
        return j+1;//注意一下,不然最后一个进不来
    }
}
  • 时间复杂度:使用for循环遍历了一遍,所以时间复杂度是 O ( n ) \mathcal{O}(n) O(n)
  • 空间复杂度:原地算法,没有开辟新的空间,空间复杂度是个常数 O ( 1 ) \mathcal{O}(1) O(1)

27. 移除元素 Remove Element

  • 难度:简单
  • 这个题在26之后,但是显然需要绕的弯没有26题多,于是做完26再做27,就不会觉得有过多的障碍。
  • 题目:给你一个数组nums和一个值 val,你需要 原地 移除所有数值等于 val的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O ( 1 ) \mathcal{O}(1) O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
  • 注意点:
  • 1.这个题的j同样是从0开始遍历的。不过这一题的i是也是要从0开始遍历,因为第一个元素同样有可能满足nums[0] == val,这种情况下是要移除的。
  • 2.这里为什么是j++呢,主要是发现了一个不等于val的值,需要先直接修改其值再移动。一般来说j++++j的出现次数多,所以想前者比较自然,后者需要多思考一会。
class Solution {
    public int removeElement(int[] nums, int val) {
        int j = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]!=val){
                nums[j++] = nums[i];
            }
        }
        return j;
    }
}
  • 时间复杂度:同26题,使用for循环遍历了一遍,所以时间复杂度是 O ( n ) \mathcal{O}(n) O(n)
  • 空间复杂度:原地算法,也没有开辟新的空间,空间复杂度是个常数 O ( 1 ) \mathcal{O}(1) O(1)

  • 这一期的总结:
  • 1.去重之类的题可以用快慢指针遍历解决;
  • 2.细节要非常注意!26题要注意从何处开始比较,以及最后一个元素在循环中实际上是没有包含的,所以要加一个返回。边界条件比较烦,很容易做错。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值