持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
题目来源
题目介绍
给你一个数组 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;
};
执行结果,可以看到是正确的。
官方优化解答与分析
官方的解答确实很精妙,通过双指针解法,双指针解法大多数是从首和尾同时进行, 因此需要初始化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;
};
总结
这道题的难度是属于简单类别的,首先基础的解法,我想大部分人都会,主要是双指针解法,会不会想得到。个人感觉数组类算法题,很多时候都可以用双指针解答法来设计,所以这一类题目需要做好归纳。