题目:将数组中的 所有 0 都移动到末尾,如输入[1,0,3,0,11,0],输出[1,3,11,0,0,0]。要求:
- 只移动 0, 其他数字顺序不变
- 考虑时间复杂度
- 必须在原数组进行操作
分析:
传统方式(不可取)
-
- 遍历数组
- 遇到 0 push 到数组末尾
- 然后用 splice截取掉当前元素
- 时间复杂度:O(n^2)
双指针方式:
-
- 指针1 指向第一个0,指针2只想第一个非0
- 把指针 和指针2 进行交换
- 指针后移
代码实现:
- 传统方式(不可取,时间复杂度为:O(n^2)):
/*** 移动 0 到数组末尾 -- 嵌套循环* @param arr 数组*/ export function moveZero(arr: number[]):void{const length = arr.lengthif(length === 0 ) return let zeroLength = 0for(let i = 0; i < length - zeroLength; i++){if(arr[i] === 0){arr.push(0)arr.splice(i,1) // 删除当前元素,splice 本身就是O(n)的复杂度zeroLength++i--// 数组截取了一个元素,i要递减,否则连续0 会有问题 }} }
- 双指针方式
/*** 移动 0 到数组末尾 -- 双指针* @param arr * @returns */ export function moveZero2(arr: number[]):void{const length = arr.lengthif(length === 0 ) return let j = -1; // 第一个为0 的索引值 let i for(i = 0; i < length; i++){if(arr[i] === 0 && j === -1){ //将j 指向第一个为0 的位置j = i}//如果i 所在位置的值不为0 ,就将j 位置的 0 交换;j指向下一个if(arr[i] !== 0 && j >= 0){arr[j] = arr[i]arr[i] = 0j++}} }
测试用例:
/*** @description 移动 0 到数组末尾 测试*/ import {moveZero,moveZero2} from './moveZero'describe('移动 0 到数组末尾',()=>{it('正常情况', ()=>{const arr = [1,0,3,4,0,0,0,11,0]moveZero2(arr)expect(arr).toEqual([1,3,4,11,0,0,0,0,0])})it('没有0', ()=>{const arr = [1,3,4,11]moveZero2(arr)expect(arr).toEqual([1,3,4,11])})it('全是0', ()=>{const arr = [0,0,0,0]moveZero2(arr)expect(arr).toEqual([0,0,0,0])})it('正常情况', ()=>{const arr = [1,0,3,4,0,0,0,11,0]moveZero(arr)expect(arr).toEqual([1,3,4,11,0,0,0,0,0])})it('没有0', ()=>{const arr = [1,3,4,11]moveZero(arr)expect(arr).toEqual([1,3,4,11])})it('全是0', ()=>{const arr = [0,0,0,0]moveZero(arr)expect(arr).toEqual([0,0,0,0])}) })