27. 移除元素

LeetCode

描述

  • 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
  • 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
  • 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

注意:

  • 原地 删除重复出现的元素,表示必须在原数组上操作

  • 方法返回的是一个长度,表示过滤后的个数,但并不代表是过滤后的数组长度。

    1
    2
    3
    4
    5
    6
    7
    8
    //给定 nums = [0,1,2,2,3,0,4,2], val = 2,

    //函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

    //注意这五个元素可为任意顺序。

    //你不需要考虑数组中超出新长度后面的元素。

  • 为什么返回数值是整数,但输出的答案是数组呢?
    输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

    1
    2
    3
    4
    5
    6
    7
    8
    // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
    int len = removeDuplicates(nums);

    // 在函数里修改输入数组对于调用者是可见的。
    // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
    for (int i = 0; i < len; i++) {
        print(nums[i]);
    }

1.暴力解法 逐个删除

1
2
3
4
5
6
7
8
9
10
11
12
var removeElement = function (nums, val) {
var i = 0,
len = nums.length;
for (; i < len; i++) {
if (nums[i] === val) {
nums.splice(i, 1)
len--;
i--;
}
}
return len;
};

2. 双指针

  • nums[j]与给定的值相等时,递增 j以跳过该元素。只要 nums[j]!==val,就复制 nums[j]nums[i]并同时递增两个索引。重复这一过程,直到 j到达数组的末尾,该数组的新长度为 i

  • 此解法和(26)删除排序数组中的重复项相似

1
2
3
4
5
6
7
8
9
10
11
12
var removeElement = function (nums, val) {
var i = 0,
j = 0,
len = nums.length;
for (; j < len; j++) {
if (nums[j] !== val) {
nums[i] = nums[j];
i++
}
}
return i;
};

复杂度分析

  • 时间复杂度:,假设数组总共有 个元素, 最多遍历 次。

  • 空间复杂度:

3. 双指针 交换位置

  • 考虑数组包含很少的要删除的元素的情况。例如,,。之前的算法会对前四个元素做不必要的复制操作。似乎没有必要将 这几个元素左移一步,因为问题描述中提到元素的顺序可以更改。
1
2
3
4
5
6
7
8
9
10
11
12
13
var removeElement = function (nums, val) {
var i = 0,
j = nums.length;
while (i < j) {
if (nums[i] === val) {
nums[i] = nums[j - 1];
j--;
} else {
i++
}
}
return i;
};

复杂度分析

  • 时间复杂度:

  • 空间复杂度:

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2025 SunZhiqi

此时无声胜有声!

支付宝
微信