返回

代码实现[leetcode]27. 移除元素问题的方法

闲谈




## [LeetCode]27. 移除元素

**问题** 

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

**示例** 

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2
解释:移除所有值为 3 的元素后,nums = [2,2]。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5
解释:移除所有值为 2 的元素后,nums = [0,1,3,0,4]。


**思路** 

这道题有两种比较简单的解法:拷贝覆盖和倒序遍历。

**方法一:拷贝覆盖** 

这种方法的思想是:从左到右遍历数组,当遇到一个不等于 val 的元素时,就将其复制到数组的前面,并更新数组的长度。

```java
public int removeElement(int[] nums, int val) {
    int n = nums.length;
    int i = 0;
    for (int j = 0; j < n; j++) {
        if (nums[j] != val) {
            nums[i] = nums[j];
            i++;
        }
    }
    return i;
}

方法二:倒序遍历

这种方法的思想是:从右到左遍历数组,当遇到一个等于 val 的元素时,就将其删除。

public int removeElement(int[] nums, int val) {
    int n = nums.length;
    int i = n - 1;
    while (i >= 0) {
        if (nums[i] == val) {
            nums[i] = nums[n - 1];
            n--;
        }
        i--;
    }
    return n;
}

这两种方法的时间复杂度都是 O(n),其中 n 是数组的长度。空间复杂度都是 O(1),因为它们不需要额外的空间。

注意事项

在实现这道题时,需要注意以下几点:

  • 如果你使用拷贝覆盖的方法,需要确保在复制元素时,不会覆盖到已经复制过的元素。
  • 如果你使用倒序遍历的方法,需要确保在删除元素时,不会删除到已经删除过的元素。
  • 你需要返回移除后数组的新长度。

延伸

这道题还可以使用更高级的方法来解决,例如双指针法。双指针法的时间复杂度为 O(n),空间复杂度为 O(1)。

public int removeElement(int[] nums, int val) {
    int i = 0;
    int j = 0;
    while (j < nums.length) {
        if (nums[j] != val) {
            nums[i] = nums[j];
            i++;
        }
        j++;
    }
    return i;
}