刷题系列之27. 移除元素

47 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

题目来源

leetcode.cn/problems/re…

题目介绍

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

题目分析

根据题目意思,我们要知道的是已知一个数组和一个已知的值,要移除数组中值和已知值相等的元素,然后返回一个新数组长度。

题目要求返回的是一个长度,所以我们可以初始一个长度变量newLength为0,方法结束后返回,然后通过循环数组,如果遇到不同的值,则变量+1,并且给对应nums[newLength]位置元素重新赋值,最终变量的值就是要的结果,并且元素对应相同的值也被移除了。

题目解答

我们根据提示思路,运用JS写法如下

/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let newLength = 0;
    for(let i = 0;i < nums.length;i++){
        if(nums[i] != val){
            nums[newLength++] = nums[i]
        }
    }
    return newLength;
};

执行结果,可以看到是正确的。

image.png

官方优化解答与分析

官方的解答确实很精妙,通过双指针解法,双指针解法大多数是从首和尾同时进行, 因此需要初始化2个变量,左边left=0,右边right等于数组长度。

接着第二部思路就是一个while循环,通过左边跟右边的比较来判断。 循环的处理就是题目所要求的,如果nums[left]等于val,那么把最右边的元素的值赋值当前下标元素,然后右边往前挪一位,即right--。

如果nums[left]不等于val,那么继续往下一个判断,即left++。

直到left大于right,那么跳出循环,这时候left的值就是我们所求的长度了,并且相对应的打印left长度数组的值即也符合要求。

var removeElement = function(nums, val) {
    let left = 0, right = nums.length;
    while (left < right) {
        if (nums[left] === val) {
            nums[left] = nums[right - 1];
            right--;
        } else {
            left++;
        }
    }
    return left;
};

总结

这道题的难度是属于简单类别的,首先基础的解法,我想大部分人都会,主要是双指针解法,会不会想得到。个人感觉数组类算法题,很多时候都可以用双指针解答法来设计,所以这一类题目需要做好归纳。