我正在进行leetCode练习,但我不知道为什么递减的for循环有效,而递增的相同代码却无效。有人可以解释为什么吗?这是问题所在:
给出一个数组num和一个值val,就地删除该值的所有实例并返回新的长度。
不要为另一个数组分配额外的空间,必须通过使用O(1)额外的内存就地修改输入数组来做到这一点。
可以更改元素的顺序。超出新长度后剩下的都无所谓。
//不工作
var removeElement = function(nums, val) {
for(let i = nums.length -1; i >= 0; i--){
if(val == nums[i]) {
nums.splice(i, 1);
}
}
return nums.length;
};
//工作
var removeElement = function(nums, val) {
for (let i = nums.length - 1; i >= 0; i--){
if (nums[i] == val){
nums.splice(i, 1);
}
}
return nums.length;
};
答案 0 :(得分:2)
这是一个众所周知的问题,就是“就地”改变数组,而向后工作是标准的解决方法。
每当删除当前元素时,便从该点开始修改任何元素的索引。
尤其是,如果您正在向前移动,则在删除元素i
时,您需要在下一遍重新考虑该元素,因为之前的元素i + 1
是什么现在,拼接是元素i
,因此您必须跳过增量:
const removeElement = function(nums, val) {
for (let i = 0; i < nums.length; ) {
if (val === nums[i]) {
nums.splice(i, 1);
} else {
++i;
}
}
return nums.length;
};
向后工作可以避免该问题,因为您已经看到了那些(现在已重新编号)元素。