将一个数组旋转 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 更好

      

 

posted @   yangkangkang  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示