# 移除元素(27)
# 题目
给你一个数组 nums 和一个值 val,你需要原地
移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地
修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
# 示例
给定 nums = [3,2,2,3]
, val = 3,
函数应该返回新的长度 2
, 并且 nums
中的前两个元素均为 2, 2
。
你不需要考虑数组中超出新长度后面的元素。
给定 nums = [0,1,2,2,3,0,4,2]
, val = 2
,
函数应该返回新的长度 5
, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4
。注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
# 算法
# 覆盖
从第一项开始遍历,将和val不同的项依次覆盖到数组的前n项,n即为结果
function removeElement(nums, val) {
let n = 0
for(let i = 0; i < nums.length; i++) {
if (nums[i] !== val) {
nums[n] = nums[i]
n++
}
}
return n
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 交换
交换移除
:遍历nums,左指针指向第一个元素位置0,右指针指向最后一个元素位置length-1。遍历开始左指针+1,当当前值与val相同时,交换左右指针的值,此时左指针-1,右指针-1,遍历的结束位置(之后全部是val相等的值)应该也-1。所以length即为结果
function removeElement(nums, val) {
let length = nums.length;
let i = 0,
j = nums.length - 1;
for (; i < length; i++) {
if (nums[i] === val) {
let temp = nums[i];
nums[i] = nums[j];
temp = nums[j];
i--;
j--;
length--;
}
}
return length;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 双指针
双指针
:类似方法二,左指针指向第一个元素,右指针指向最后一个元素,若左指针遇到等于val的值,则使用右指针的值覆盖左指针,此时右指针-1;若左指针的值不等于val,那么左指针+1。结束条件是左指针大于右指针。左指针指向的第i个位置即为结果i
function removeElement(nums, val) {
let i = 0,
j = nums.length - 1;
while (i <= j) {
if (nums[i] === val) {
nums[i] = nums[j];
j--;
} else {
i++;
}
}
return i;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# splice()
遍历数组,遇到等于val的值则使用splice()
删除
function removeElement(nums, val) {
for (let i = 0; i < nums.length; i++) {
if (nums[i] === val) {
nums.splice(i, 1);
i--;
}
}
return nums.length;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9