移除元素
题目链接:移除元素
示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,_,_,_]
解释:你的函数应该返回 k = 5,并且 nums 中的前五个元素为 0,0,1,3,4。
注意这五个元素可以任意顺序返回。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。
采用双指针算法,slow指针记录需要被覆盖的下表,fast指针去遍历数组。
代码:
class Solution {
public int removeElement(int[] nums, int val) {
int slowIndex=0;
for(int fastIndex=0;fastIndex<nums.length;fastIndex++){
if(nums[fastIndex]!=val){
nums[slowIndex++]=nums[fastIndex];
}
}
return slowIndex;
}
}
GPT的解释
国内直接使用:点我跳转
- 使用一个指针遍历整个数组(称为
i
),另一个指针(称为k
)记录当前可以放置有效元素的位置。 - 每次遇到
nums[i] != val
,就将nums[i]
赋值到nums[k]
,并递增k
,表示有效的元素数量增加。 - 最后返回
k
,它表示数组中不等于val
的元素的数量。
Java 代码实现
class Solution {
public int removeElement(int[] nums, int val) {
// 初始化指针 k,表示当前有效元素应存放的位置
int k = 0;
// 遍历数组中的每一个元素
for (int i = 0; i < nums.length; i++) {
// 如果当前元素不等于目标值 val
if (nums[i] != val) {
// 将该元素放入 nums[k] 位置,k 随之递增
nums[k] = nums[i];
k++;
}
}
// 返回 k,表示有效元素的个数
return k;
}
}
解释
-
指针 k 的作用:
k
记录了新数组的下一个可放置位置。当遇到一个不等于val
的元素时,nums[k]
被赋值为这个元素,k
然后递增。
-
遍历数组:
- 使用一个
for
循环遍历整个数组,当nums[i] != val
时,我们就将该元素放到nums[k]
的位置,并且将k
递增。这样,所有有效元素(即不等于val
的元素)都被移到了数组的前面。
- 使用一个
-
时间复杂度:
- 该算法只遍历了数组一次,所以时间复杂度为 O(n),其中
n
是数组的长度。
- 该算法只遍历了数组一次,所以时间复杂度为 O(n),其中
-
空间复杂度:
- 该算法使用了常数级别的额外空间,即 O(1)。
示例1的解释:
输入:
nums = [3, 2, 2, 3], val = 3
执行步骤:
i = 0
,nums[0] == 3
,跳过。i = 1
,nums[1] == 2
,放入nums[0]
,k++
。i = 2
,nums[2] == 2
,放入nums[1]
,k++
。i = 3
,nums[3] == 3
,跳过。
最后 k = 2
,数组的前两个元素是 [2, 2]
。
示例2的解释:
输入:
nums = [0, 1, 2, 2, 3, 0, 4, 2], val = 2
执行步骤:
i = 0
,nums[0] == 0
,放入nums[0]
,k++
。i = 1
,nums[1] == 1
,放入nums[1]
,k++
。i = 2
,nums[2] == 2
,跳过。i = 3
,nums[3] == 2
,跳过。i = 4
,nums[4] == 3
,放入nums[2]
,k++
。i = 5
,nums[5] == 0
,放入nums[3]
,k++
。i = 6
,nums[6] == 4
,放入nums[4]
,k++
。i = 7
,nums[7] == 2
,跳过。
最终 k = 5
,数组的前五个元素是 [0, 1, 3, 0, 4]
。
这个方法可以有效地解决问题,并且符合题目对时间和空间复杂度的要求。