leetcode
leetcode copied to clipboard
283. 移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。 尽量减少操作次数。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/move-zeroes 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
- 普通循环
倒序循环确保删除元素之后不会改变后面的索引, 然后同时往数组里面
push(0)保持数组长度
const moveZeroes = nums => {
let i = nums.length
while (i--) {
const curr = nums[i]
if (curr === 0) {
nums.splice(i, 1)
nums.push(0)
}
}
}
- 双指针 - 思路1
- 思路讲解
! 第一次循环
i=0
[0,1,0,3,12]
j=0
! 由于nums[i]等于0, 所以不做任何操作, i++
! 第二次循环
i=1
[0,1,0,3,12]
j=0
! 因为nums[i]不为0, 然后赋值nums[j]=nums[i]; i++; j++
! 第三次循环
i=2
[1,1,0,3,12]
j=1
! 此时nums[i]等于0, 所以不作任何事, i++
! 第四次循环
i=3
[1,1,0,3,12]
j=1
! 现在nums[i]不为0, 再次赋值nums[j]=nums[i]; i++; j++
! 第五次循环 (最后一次循环)
i=4
[1,3,0,3,12]
j=2
! 此时nums[i]不为0, 再次赋值nums[j]=nums[i]; i++; j++
! 循环结束, 现在数组变成了这样
[1,3,12,3,12]
j=3
! 最后一步操作, 让数组中索引>=j的元素全部赋值为0
! 此时函数结束, 数组移动完毕
[1,3,12,0,0]
const moveZeroes = nums => {
let j = 0
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== 0) {
nums[j++] = nums[i]
}
}
for (let i = j; i < nums.length; i++) {
nums[i] = 0
}
return nums
}
- 双指针 - 思路2
思路是只要遇到 0 就与后面的非零项进行交换, 直到全部交换完毕
先通过start = nums.indexOf(0)判断起始点, 如果得到start = -1就直接 return
! 第一次循环
i=0
[0, 1, 0, 3, 12]
j=0
! 此时nums[i]等于0, 跳过, i++
! 第二次循环
i=1
[0, 1, 0, 3, 12]
j=0
! nums[i]不为0, 则nums[j]和nums[i]交换, i++, j++
! 第三次循环
i=3
[1, 0, 0, 3, 12]
j=1
! nums[i]等于0, 跳过, i++
! 第四次循环
i=3
[1, 0, 0, 3, 12]
j=1
! nums[i]不为0, 则nums[j]和nums[i]交换, i++, j++
! 第五次循环
i=3
[1, 3, 0, 0, 12]
j=1
! nums[i]不为0, 则nums[j]和nums[i]交换, i++, j++
! 循环结束, 数组最后变成
[1, 3, 12, 0, 0]
const moveZeroes = nums => {
let start = nums.indexOf(0)
if (start === -1) return nums
for (let i = start, j = start; i < nums.length; i++) {
if (nums[i] !== 0) {
nums[j++] = nums[i]
nums[i] = 0
}
}
}