Rearch Interest: Visualization">
27. 移除元素
题目描述
给你一个数组nums
和一个值val
,你需要原地移除所有数值等于val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用\(O(1)\)额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例1: >输入:nums = [3,2,2,3]
, val = 3
>输出:2
, nums = [2,2]
>解释:函数应该返回新的长度 2
, 并且 nums
中的前两个元素均为
2
。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为
2
,而 nums = [2,2,3,3]
或
nums = [2,2,0,0]
,也会被视作正确答案。
示例2: >输入:nums = [0,1,2,2,3,0,4,2]
,
val = 2
>输出:5
,
nums = [0,1,4,0,3]
>解释:函数应该返回新的长度
5
, 并且 nums
中的前五个元素为
0, 1, 3, 0, 4
。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
我的代码
\(T(N) = O(N)\), \(S(N) = O(1)\)
1 | class MySolution27 |
方法一:双指针
\(T(N) = O(N)\), \(S(N) = O(1)\)
i
为快指针,j
为慢指针。
当nums[j]=val
时,递增j
跳过该元素,i
不动。
当nums[j]≠val
时,就将nums[j]
复制到nums[i]
,并同时递增i
和j
。
直到j到达数组末尾,则新数组长度为i
。
假设数组总共有 n
个元素,i
和
j
至少遍历 2n
步。
1 | class Solution |
方法二:双指针 - 当要删除的元素很少时
\(T(N) = O(N)\), \(S(N) = O(1)\)
现在考虑数组包含很少的要删除的元素的情况。
例如,num=[1,2,3,5,4]
,val=4
。
之前的算法会对前四个元素做不必要的复制操作。 另一个例子是
num=[4,1,2,3,5]
,val=4
。 似乎没有必要将
[1,2,3,5]
这几个元素左移一步,因为问题描述中提到元素的顺序可以更改。
当我们遇到 nums[i] = val
时,
我们可以将当前元素与最后一个元素进行交换,并释放最后一个元素。
这实际上使数组的大小减少了 1
。
请注意,被交换的最后一个元素可能是您想要移除的值。 但是不要担心,在下一次迭代中,我们仍然会检查这个元素。
在这个方法中,赋值操作的次数等于要删除的元素的数量。 因此,如果要移除的元素很少,效率会更高。
1 | class Solution |