将一个数组旋转 k 步
题目:将一个数组旋转 k步。如输入一个数组[1,2,3,4,5,6,7] 和 k = 3, 即旋转 3步。输出 [5,6,7,1,2,3,4]
解题思路:
-
- 思路1: 把k 后面的元素,挨个pop,然后unshif 到数组前面
- 思路2:
- 将 k 后面的所有数据拿出来作为 part1
- 将 k前面的所有数据拿出来作为part2
- 返回 part1.concat(part2)
代码演示:
- 思路1 代码
/** * 旋转数组 k 步 - 使用pop、unshift * @param arr arr * @param k k * @returns arr */ export function rotate1(arr: number[], k: number): number[]{ const length = arr.length; if(!k || length === 0){ return arr } // 处理 k 为负数 和 数值大于数组长度的情况 const step = Math.abs(k % length) // 时间复杂度: 一次循环 O(n) 嵌套 unshitf O(n) = O(n^2)
// 空间复杂度: O(1)
for(let i = 0; i < step; i++){ const n = arr.pop() if(n){ arr.unshift(n) // 数组的 unshift、shift、splice 本身是O(n)的时间复杂度 } } return arr } - 思路2 代码
/** * 旋转数组 K 步 - 使用 concat * @param arr arr * @param k k * @returns arr */ export function rotate2(arr:number[], k: number){ const length = arr.length; if(!k || arr.length === 0){ return arr } const step = Math.abs( k % length) //时间复杂度:O(1);空间复杂度:O(n) + O(n) + O(n) = 3*O(n)= O(n) const part1 = arr.slice(-step) //空间复杂度 O(n) const part2 = arr.slice(0, length - step) //空间复杂度 O(n) const part = part1.concat(part2) //空间复杂度 O(n) return part }
复杂度分析
时间复杂度
-
- 思路1:看代码有一个循环所以是O(n), 但数组的unshif()方法本身也是一个O(n)复杂度;所以实际复杂度是O(n^2)
- 思路2: O(1)。slice 和 concat 不会修改原数组,所以复杂度是O(1)
空间复杂度
-
- 思路1:O(1)
- 思路2:O(n)
性能测试:
测试代码:
import {rotate1,rotate2 } from './01-algorithm/array-rotate.ts' const arr = [] for (let i = 0; i<100000 ; i++){ arr.push(i) } console.time('rotate1') rotate1(arr,90000) console.timeEnd('rotate1') // 546ms console.time('rotate2') rotate2(arr,90000) console.timeEnd('rotate2') //1ms
执行结果:
有性能测试发现:思路2 比思路1 更好
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!