一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情。
本题难度:⭐ ⭐ ⭐
本题类型:算法、手写
阿林最近忙爆了,真的没时间认真写文章了,但是再忙也不能忘了学习,不然就懈怠了,最近多更新点前端面试中出现的高频算法题吧,这个写起来简单。
题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下 原地 对数组进行操作。
原题地址:leetcode-283. 移动零
题目要求:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
输入: nums = [0]
输出: [0]
解题思路
在题目中看到了 原地 这样的字眼,直接使用双指针,这道题用快慢指针。
思路是:
- 定义慢指针
i,快指针j - 两个指针一起往后走,遇到指向为
0的情况,慢指针就停下来,快指针则不管,一直往后走 - 如果
nums[j] !== 0 && nums[i] === 0,快慢指针位置的元素交换位置 - 快指针走完,循环结束。
先用文字“画图”,理清思路:
初始化:
i
[1,0,1,0,3,12]
j
下一步:
i
[1,0,1,0,3,12]
j
下一步:
i
[1,0,1,0,3,12]
j
这里要注意
此时,nums[j] !== 0 && nums[i] === 0
交换位置,然后 i++,j++
下一步:
i
[1,1,0,0,3,12]
j
下一步:
i
[1,1,0,0,3,12]
j
下一步:
i
[1,1,3,0,0,12]
j
下一步:
i
[1,1,3,12,0,0]
j
循环结束。
编码实现
写代码的时候还是要语意化,定义快指针为 fast,慢指针为 slow。
// 快慢指针
function moveZeroes(nums) {
let slow = 0, fast = 0
while(fast < nums.length) {
// 快指针指向不为0,慢指针指向为0,交换
if (nums[fast] !== 0 && nums[slow] === 0) {
[nums[fast],nums[slow]] = [nums[slow],nums[fast]]
slow++
}
// 慢指针指向不为0,才往后走,否则慢指针不动
if (nums[slow] !== 0) {
slow++
}
// 快指针一直往后面走
fast++
}
return nums
}
这里有一个细节,交换快慢指针对应的元素是这么写的:
[nums[fast],nums[slow]] = [nums[slow],nums[fast]]
一般我们交换数组里的两个元素都是这么写的:
- 定义一个临时变量
temp temp = arr[i]arr[i] = arr[j]arr[j] = temp
在 JS 中,可以使用 解构赋值 语法来实现数组元素的交换,代码更简洁。
// swap1 和 swap2 效果完全一样
function swap1(arr, i, j) {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
return arr
}
function swap2(arr, i, j) {
[arr[i], arr[j]] = [arr[j], arr[i]]
return arr
}
console.log(swap1([1,2], 0, 1)) // 输出 [2,1]
console.log(swap2([1,2], 0, 1)) // 输出 [2,1]
回到本题,细心地同学还可以发现,上面的逻辑其实有冗余。
- 慢指针的指向是 0 时,交换后会往后走。
- 慢指针的指向不是 0 时,也会往后走。
可以合并一下代码,合并后代码如下:
function moveZeroes(nums) {
let slow = 0, fast = 0
while(fast < nums.length) {
if (nums[fast] !== 0) {
[nums[fast],nums[slow]] = [nums[slow],nums[fast]]
slow++
}
fast++
}
return nums
}
这样看上去代码就简洁多了。
写代码就是这样,除非你经验非常丰富,否则很难一步就写出优质的代码。我们要做的是先理清思路,把功能实现,再去慢慢优化代码。
一步一个脚印,多去训练,慢慢地你的代码就会越写越好。
运行结果
vscode leetcode 插件 yyds! 上班“认真工作”的神器 🐶
结尾
阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
我是阿林,输出洞见技术,再会!
上一篇:
下一篇: