为什么递减的for循环可以解决此问题,而递增的循环却不能解决?

时间:2020-01-27 12:42:17

标签: javascript arrays

我正在进行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;
};

1 个答案:

答案 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;
};

向后工作可以避免该问题,因为您已经看到了那些(现在已重新编号)元素。