给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。

  • 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
  • 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
  • 示例 1:
  • 给定 nums = [3,2,2,3], val = 3,
  • 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
  • 你不需要考虑数组中超出新长度后面的元素。

1.拷贝覆盖

主要思路:定义一个变量,对不重复的值计数。for循环完成。

存在的问题 就是值可以计算出当前不相同值,数组的值是不符合要求的。

这种思路在移除元素较多时更适合使用,最极端的情况是全部元素都需要移除,遍历一遍结束即可

时间复杂度:O(n) 空间复杂度O(1)

public static int removeElement3(int [] nums,int val){
        int count = 0;
        for (int num:nums) {
            if (num!=val){
                nums[count++] = num;
            }
        }
        return count;
    }

2.交换移除

主要思路:用一个变量去记录数组的长度,然后处理两种情况,一种是当前的值等于val 就将数组中最后的值赋值给当前相同的值,m 用来不断减少数组的长度。否则的话 是另一种情况 如果不相等 直接i++ 判断下一个就可以。

这种思路在移除元素较少时更适合使用,最极端的情况是没有元素需要移除,遍历一遍结束即可

时间复杂度:O(n),空间复杂度:O(1)

public static int removeElement4(int [] nums,int val){
        int m = nums.length;
        for (int i = 0; i < m; ) {//注意for 这里不能i++ i是用来确认哪些数据不是要寻找的
            if (nums[i] == val){
                nums[i] = nums[m-1];
                m--;
            }else {
                i++;
            }
        }
        return m;
    }

3.双指针

实现思路:一个快指针 一个慢指针。用快指针来判断是否相等 不相等赋值给慢指针,慢指针的作用是来定位前面如果有重复的直接跳过去。

时间复杂度:o(n)

空间复杂度:o(1)

public static int removeElement5(int [] nums,int val){
        int i = 0;
        for (int j = 0; j < nums.length; j++) {
            if (nums[j]!=val){
                nums[i] = nums[j];
                i++;//加1
            }
            //如果相等 不做 等待下标i来进行覆盖
        }
        return i;
    }

4.双指针 —当要删除的元素很少时

实现思路:通过快慢指针 在一种比较极端的情况下。nums[1,2,3,5,4] val = 4 在最后才可以找到需要删除的元素,虽然nums中的值没有改变,但是通过m-- 停止了循环 i=4。

当我们遇到 nums[i] = valnums[i]=val 时,我们可以将当前元素与最后一个元素进行交换,并释放最后一个元素。这实际上使数组的大小减少了 1。

时间复杂度:O(n)

空间复杂度:O(1)

public static int removeElement6(int [] nums,int val){
        int i = 0;
        int m = nums.length;
        while (i<m){
            if (nums[i] == val){//相当的话 直接将快指针元素赋值给慢指针
                nums[i] = nums[m-1];
                m--;
            }else {
                i++;//不相等 直接跳过
            }
        }
        return i++;
    }