JavaScript数组旋转K步:两种实现思路与复杂度对比

作者:函数茶馆

时间:2026-10-25

浏览:264

本文详细解析JavaScript中将数组旋转k步的两种常见实现方式。第一种通过循环调用pop和unshift操作,虽然空间复杂度低但时间复杂度较高;第二种利用slice或splice结合concat进行数组切片重组,牺牲空间换取更快的执行速度。文章对比了两种方法的时间与空间复杂度,并结合前端开发中“重时间轻空间”的原则,推荐更优的解决方案,同时强调单元测试与边界条件处理的重要性。

文章目录

一、题目描述:

实现一个功能,将给定的数组元素整体向右旋转k个位置。

  • 例如输入一个包含数字的数组[1,2,3,4,5,6,7,8]
  • 设定旋转步数k=3,即需要向右移动3个位置
  • 期望输出结果为[6,7,8,1,2,3,4,5]

二、思路分析:

针对该问题,主要存在两种不同的解决思路:

  • 方法一:通过循环将数组末尾元素逐个弹出(pop),再插入到数组头部(unshift)。
  • 方法二:利用数组切片功能将数组拆分为两部分,最后通过拼接(concat)合并。

思路1:把末尾的元素挨个pop,然后unshift到数组后面

  • JavaScript Array pop() 方法

该方法用于删除并返回数组的最后一个元素:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.pop();
  • JavaScript Array unshift() 方法

该方法用于向数组的开头添加一个或多个新元素,并返回新长度:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon","Pineapple");

TS代码

function rotate1(arr:number[],k:number):number[]{
    const length = arr.length
    if(!k||length===0)return arr
    const step = Math.abs(k%length)

    for(let i =0;i<step;i++){
        const n = arr.pop()
        if(n){
            arr.unshift(n)
        }
    }
    return arr
}
const arr = [1,2,3,4,5,6,7,8]
const arr1 = rotate1(arr,3)
console.log(arr1)

运行结果

一、题目描述:

思路2:把数组拆分,最后concat拼接到一起

JavaScript Array slice() 方法

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3);

JavaScript 数组 Const

const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);
// expected output: Array ["a", "b", "c", "d", "e", "f"]

TS代码

/**
 * 旋转数组K步 -使用concat
 * @param arr arr 
 * @param k k 
 * @returns arr
 */
function rotate2(arr:number[],k:number):number[]{
    const length = arr.length
    if(!k || length===0) return arr
    const step = Math.abs(k%length)

    const part1 = arr.splice(-step)
    const part2 = arr.splice(0,length-step)
    arr = arr.concat(part1,part2)
    return arr   
}
const arr2 = [1,2,3,4,5,6,7,8]
const arr3 = rotate2(arr2,3)

console.log(arr3)

运行结果

一、题目描述:

三、总结:

在分析代码并整理思路后,应尽可能寻找最优解。编写代码时不仅要进行功能测试,还要养成编写单元测试的习惯,以确保程序的健壮性。

复杂度分析:

  • 思路1的时间复杂度为O(n^2),空间复杂度为O(1)
  • 思路2的时间复杂度为O(1),空间复杂度为O(n)

在前端开发场景中,通常更看重执行时间而非内存占用,因此思路2的表现更佳。

时间复杂度O(1)和O(n)差别很大

一、题目描述:5. 数组是一个有序结构,数组的unshift、shirt、splice操作都很慢,pop和push都很快,.slice不会改变原数组,时间复杂度为0(1)

//性能测试
const arr4 = []
for(let i =0;i<10 * 10000;i++){
    arr4.push(i)
}
console.time('rotate1')
rotate1(arr4,9*10000)
console.timeEnd('rotate1')

const arr5 = []
for(let i=0;i< 10 * 10000;i++){
    arr5.push(i)
}
console.time('rotate2')
    rotate2(arr5,9*10000)
    console.timeEnd('rotate2')

一、题目描述:

四、划重点

  • 注意算法时间复杂度(前端重时间,轻空间)
  • 识破内置API的时间复杂度(如unshift为0(n))
  • 单元测试,考虑参数非法情况,提升代码健壮性

到此这篇关于JavaScript算法题之如何将一个数组旋转k步的文章就介绍到这了,更多相关JavaScript数组旋转k步内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章