【前端算法】将一个数组旋转K步

简介: 使用typescript完成将一个数组旋转K步的过程
  • 输入一个数组[1, 2, 3, 4, 5, 6, 7]
  • k = 3, 即旋转3步
  • 输出[5, 6, 7, 1, 2, 3, 4]

思路

  • 1、把末尾的元素挨个 pop ,然后 unshift 到数组前面
  • 2、把数组拆分,最后concat 拼接到一起

代码示例1

function rotate1 (arr: number[], k?:number): number[] {
  const len = arr.length
  if (!k || len === 0) return arr;

  const step = Math.abs(k % len); // 取绝对值,防止step大于数组长度的情况

  for (let i = 0; i < step; i++) {
    const n = arr.pop()

    if (typeof n !== "undefined") {
      arr.unshift(n)
    }
  }

  return arr;
}

代码示例2

function rotate2 (arr: number[], k?: number): number[] {
  const len = arr.length
  if (!k || len === 0) return arr;

  const step = Math.abs( k % len); // 取绝对值,防止step大于数组长度的情况

  const part1 = arr.slice(-step);
  const part2 = arr.slice(0,len - step);
  const part3 = part1.concat(part2)

  return part3
}

关于 k % len 当k是字符串时,取余的结果是NaN。在示例1中 i < NaN === false, 在示例2中arr.slice(-NaN) === arr

功能测试

const res = rotate1([1, 2, 3, 4, 5, 6, 7],-3)
const res2 = rotate2 ([1, 2, 3, 4, 5, 6, 7],-3)
console.log(res) // [5, 6, 7, 1, 2, 3, 4]
console.log(res2) // [5, 6, 7, 1, 2, 3, 4]

JEST单元测试

describe('数组旋转', () => {
    it('正常情况', () => {
        const arr = [1, 2, 3, 4, 5, 6, 7]
        const k = 3
        const res = rotate1(arr,k)
        expect(res).toEqual([5, 6, 7, 1, 2, 3, 4]) // 断言
    })
    
    it('数组为空', () => {
        const res = rotate1([],3)
        expect(res).toEqual([]) // 断言
    })
    
    it('k 是负值', () => {
        const arr = [1, 2, 3, 4, 5, 6, 7]
        const k = -3
        const res = rotate1(arr,k)
        expect(res).toEqual([5, 6, 7, 1, 2, 3, 4]) // 断言
    })
    
    it('k 是 0', () => {
        const arr = [1, 2, 3, 4, 5, 6, 7]
        const k = 0
        const res = rotate1(arr,k)
        expect(res).toEqual(arr) // 断言
    })
    
    it('k 不是数值', () => {
        const arr = [1, 2, 3, 4, 5, 6, 7]
        const k = 'abc'
        
        @ts-ignore
        const res = rotate1(arr,k)
        expect(res).toEqual(arr) // 断言
    })
})

性能测试

const testArr1 = []
for(let i = 0; i < 10 * 10000; i++){
  testArr1.push(i)
}

console.time('rotate1')
rotate1(testArr1,9 * 10000)
console.timeEnd('rotate1')

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

结果:

rotate1: 3.611s
rotate2: 1.147ms

思路2 性能 远超思路1

复杂度分析

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

数组是一个连续的内存空间,unshift操作是一个有序的操作,相当于对数组进行了一次遍历,所以非常慢!!!

所以思路1的时间复杂度不是O(n)而是O(n ^ 2)!

正确选择答案

  • 选择思路2:拆分数组,最后concat拼接,返回
  • 时间复杂度O(1),足够快
  • 空间复杂度O(n),对于前端(重时间,轻空间)可以接受
相关文章
|
27天前
|
前端开发 JavaScript 开发者
【前端开发者的福音】彻底改变你编码习惯的神奇数组迭代技巧——从基础到进阶,解锁 JavaScript 数组迭代的N种姿势!
【8月更文挑战第23天】在Web前端开发中,数组是JavaScript中最常用的数据结构之一,掌握高效的数组迭代方法至关重要。本文详细介绍了多种数组迭代技巧:从基础的`for`循环到ES6的`for...of`循环,再到高阶方法如`forEach`、`map`、`filter`、`reduce`及`some`/`every`等。这些方法不仅能提高代码的可读性和维护性,还能有效优化程序性能。通过具体的示例代码,帮助开发者更好地理解和运用这些迭代技术。
25 0
|
1月前
|
算法 测试技术
【算法】二分算法——寻找旋转排序数组中的最小值
【算法】二分算法——寻找旋转排序数组中的最小值
|
30天前
|
JavaScript 算法 前端开发
"揭秘Vue.js的高效渲染秘诀:深度解析Diff算法如何让前端开发快人一步"
【8月更文挑战第20天】Vue.js是一款备受欢迎的前端框架,以其声明式的响应式数据绑定和组件化开发著称。在Vue中,Diff算法是核心之一,它高效计算虚拟DOM更新时所需的最小实际DOM变更,确保界面快速准确更新。算法通过比较新旧虚拟DOM树的同层级节点,递归检查子节点,并利用`key`属性优化列表更新。虽然存在局限性,如难以处理跨层级节点移动,但Diff算法仍是Vue高效更新机制的关键,帮助开发者构建高性能Web应用。
39 1
|
1月前
|
存储 算法 Java
深入算法基础二分查找数组
文章深入学习了二分查找算法的基础,通过实战例子详细解释了算法的逻辑流程,强调了确定合法搜索边界的重要性,并提供了Java语言的代码实现。
深入算法基础二分查找数组
|
25天前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
|
27天前
|
存储 前端开发 JavaScript
数组操作大揭秘:Web前端开发者必备技能!
【8月更文挑战第23天】本文介绍了JavaScript中数组的基本操作方法,包括创建、添加、删除元素、获取数组长度与特定索引的元素、修改元素以及判断元素是否存在等。此外还展示了如何利用 `concat()` 方法或扩展运算符合并数组。这些实用示例有助于前端开发者更好地理解和应用数组。
25 0
|
1月前
|
算法
【算法】模拟算法——外观数组(medium)
【算法】模拟算法——外观数组(medium)
|
1月前
|
算法
【算法】前缀和——除自身以外数组的乘积
【算法】前缀和——除自身以外数组的乘积
|
1月前
|
算法
【算法】前缀和——寻找数组的中心下标
【算法】前缀和——寻找数组的中心下标
|
13天前
|
算法 BI Serverless
基于鱼群算法的散热片形状优化matlab仿真
本研究利用浴盆曲线模拟空隙外形,并通过鱼群算法(FSA)优化浴盆曲线参数,以获得最佳孔隙度值及对应的R值。FSA通过模拟鱼群的聚群、避障和觅食行为,实现高效全局搜索。具体步骤包括初始化鱼群、计算适应度值、更新位置及判断终止条件。最终确定散热片的最佳形状参数。仿真结果显示该方法能显著提高优化效率。相关代码使用MATLAB 2022a实现。