- 如输入[1,0,3,0,11,0] 输出 [1,3,11,0,0,0]
- 只移动0,其他顺序不变
- 必须在原数组进行操作
如果不限制“必须在原数组操作”
- 定义part1 part2 两个数组
- 遍历数组,非0push到part1, 0 push到part2
- 返回part1.concat(part2)
传统思路(不可用)
- 遍历数组,遇到0则push到数组末尾
- 用splice截取当前元素
- 时间复杂度是O(n^2)--算法不可用
代码演示(废弃方案)
function moveZero(arr: number[]): void{
const length = arr.length
if (length === 0) return
let zeroLength = 0
for (let i = 0; i < length-zeroLength; i++){
if (arr[i] == 0) {
arr.push(0)
arr.splice(i, 1)
i--
zeroLength++
}
}
}
const arr3 = [1, 0, 3, 4, 0, 0, 11, 0]
moveZero(arr3)
console.log(arr3);
双指针思路(任何嵌套循环都可以考虑双指针)
- 定义j指向第一个0,i指向j后面的第一个非0
- 交换i和j的值,继续向后移动
- 只遍历一次,所以时间复杂度为O(n)

代码
function moveZero2(arr: number[]): void{
const length = arr.length
if (length === 0) return
let i // 指向0后的第一个非0
let j = -1 // 指向第一个0
for (i = 0
if (arr[i] === 0) {
// 第一个0
if (j < 0) {
j = i
}
}
if (arr[i] !== 0 && j >= 0) {
// 交换
const n = arr[i]
arr[i] = arr[j]
arr[j] = n
j++
}
}
}
// 功能测试
const arr3 = [1, 0, 3, 4, 0, 0, 11, 0]
moveZero2(arr3)
console.log(arr3)
划重点
- 向面试官确认:是否必须修改原数组
- 数组是连续存储,要慎用spilce unshift等api
- 双指针思路