算法:将一个数组旋转k步
题目
输入一个数组如 [1,2,3,4,5,6,7],输出旋转 k 步后的数组。
- 旋转 1 步:就是把尾部的 7 放在数组头部前面,也就是
[7,1,2,3,4,5,6] - 旋转 2 步:就是把尾部的 6 放在数组头部前面,也就是
[6,7,1,2,3,4,5] - …
思路
思路1:将数组尾部的元素 pop,然后 unshift 到头部
思路2:将数组拆分成两段,然后通过 concat 拼接在一起
那么哪个是最优解呢?
遵循的原则:复杂度,在前端开发中重时间,轻空间。因为相应速度更重要,占内存的情况不那么重要。
代码
思路1
/*** 旋转数组 k 步 - 使用 pop 和 unshift* @param arr arr* @param k k* @returns arr*/
export function rotate1(arr: number[], k: number): number[] {const length = arr.lengthif (!k || length === 0) return arrconst step = Math.abs(k % length) // abs 取绝对值// O(n^2)for (let i = 0; i < step; i++) {const n = arr.pop()if (n != null) {arr.unshift(n) // 数组是一个有序结构,unshift 操作非常慢!!! O(n)}}return arr
}
思路2
/*** 旋转数组 k 步 - 使用 concat* @param arr arr* @param k k*/export function rotate2(arr: number[], k: number): number[] {const length = arr.lengthif (!k || length === 0) return arrconst step = Math.abs(k % length) // abs 取绝对值// O(1)const part1 = arr.slice(-step) // O(1)const part2 = arr.slice(0, length - step)const part3 = part1.concat(part2)return part3
}
测试
// 功能测试
const arr = [1, 2, 3, 4, 5, 6, 7]
const arr1 = rotate2(arr, 3)
console.info(arr1)// 性能测试
const arr1 = []
for (let i = 0; i < 10 * 10000; i++) {arr1.push(i)
}
console.time('rotate1')
rotate1(arr1, 9 * 10000)
console.timeEnd('rotate1') // 885ms O(n^2)const arr2 = []
for (let i = 0; i < 10 * 10000; i++) {arr2.push(i)
}
console.time('rotate2')
rotate2(arr2, 9 * 10000)
console.timeEnd('rotate2') // 1ms O(1)

可以看到两种方式速度相差了百倍
测试用例
import { rotate1, rotate2 } from './array-rotate'describe('数组旋转', () => {it('正常情况', () => {const arr = [1, 2, 3, 4, 5, 6, 7]const k = 3const res = rotate2(arr, k)expect(res).toEqual([5, 6, 7, 1, 2, 3, 4]) // 断言})it('数组为空', () => {const res = rotate2([], 3)expect(res).toEqual([]) // 断言})it('k 是负值', () => {const arr = [1, 2, 3, 4, 5, 6, 7]const k = -3const res = rotate2(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 = 0const res = rotate2(arr, k)expect(res).toEqual(arr) // 断言})it('k 不是数字', () => {const arr = [1, 2, 3, 4, 5, 6, 7]const k = 'abc'// @ts-ignoreconst res = rotate2(arr, k)expect(res).toEqual(arr) // 断言})
})
执行 npx jest xxx.test.ts 即可

复杂度
思路1,时间复杂度为 O(n^2),空间复杂度O(1)
思路2,时间复杂度为 O(1),空间复杂度O(n)
思路1这里为什么是 O(n^2),我们明明只有一次遍历?
答:数组是一个有序结构,unshift 操作非常慢

数组是连续的内存空间,就像这个教室的图,如果要把 F 同学放在前面(unshift操作),那么就得把 ABCDE挨个往后移动一位,所以这个操作是很慢的。但是 push、pop 操作不会,直接给后面添加/删除,前面同学不用动。
相关文章:
算法:将一个数组旋转k步
题目 输入一个数组如 [1,2,3,4,5,6,7],输出旋转 k 步后的数组。 旋转 1 步:就是把尾部的 7 放在数组头部前面,也就是 [7,1,2,3,4,5,6]旋转 2 步:就是把尾部的 6 放在数组头部前面,也就是 [6,7,1,2,3,4,5]… 思路 思…...
使用大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据
记录一下使用Java的SpringBoot大华SDK在智慧公厕项目中使大华惠智双目半球网络摄像机DH-IPC-HD4140X-E2获取人流量统计数据 首先根据说明书登录摄像头,一般摄像头都有自己的账号和密码(可能是admin admin 也可能是admin 888888 还有可能是admin 12345),…...
DC插装式流量阀压力阀
Cartridge Valves 电磁阀 止回阀 运动控制阀 流量控制阀 溢流阀 压力控制阀 顺序阀 梭阀 方向阀 配件 Zero Profile Valves 止回阀 运动控制阀 流量控制阀 溢流阀 梭阀 In-Line Valves 止回阀和梭阀 方向阀 配件 微型系列 AB20S APIDC-30S C10B C10S C10S…...
NumPy 数组学习手册:6~7
原文:Learning NumPy Array 协议:CC BY-NC-SA 4.0 译者:飞龙 六、性能分析,调试和测试 分析,调试和测试是开发过程的组成部分。 您可能熟悉单元测试的概念。 单元测试是程序员编写的用于测试其代码的自动测试。 例如&…...
【笔试强训选择题】Day6.习题(错题)解析
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、Day6习题(错题)解析 二、Day6习题(原题)练习 总结 前言 一、Day6习题(错题)解析…...
磁盘分区-LINUX
1、主分区(primary) 磁盘在Linux当中的命名: IDE /dev/hda hdb SCSI sda sdb 分区数字表示:sda1 、sda2、sda3 磁盘分区相当于给磁盘打隔断 ① 系统中必须要存在的分区,系统盘选择主分区安装 ② 数字编号只能是1-4&am…...
SpringAOP入门基础银行转账实例(进阶版)------------事务处理
SpringAOP入门基础银行转账实例**(进阶版)**------------事务处理 由上一节讲述的通过Connection和QueryRunner对事务进行的处理(详情可以去我之前写的博客文章:https://blog.csdn.net/m0_56245143/article/details/130069160?spm1001.2014…...
【python学习】基础篇-常用函数-format函数 格式化操作
format()可以对数据进行格式化处理操作,语法如下: format(value,format_spec) value 为要转换的数据,fommat spec 为格式化解释, 当参数 format spec 为空时,等同于函数 str(value)的方式。 format spec 可以设置非常复…...
团团面试经验
1、Redis同时访问大量不存在的key会发生什么? 如果是缓存和数据库中都不存在,那么就会发生缓存穿透。 举个例子:某个黑客故意制造一些非法的 key 发起大量请求,导致大量请求落到数据库,结果数据库上也没有查到对应的数…...
今天面了个京东拿 38K 出来的,让我见识到了基础的天花板
今年的春招已经开始了,很多小伙伴收获不错,拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的软件测试面试题和八股文,为此咱这里也统一做一次大整理和大归类,这也算是划重点了。 俗话说得好࿰…...
Qt创建SDK库(dll动态库)并调用SDK库(dll动态库)
Qt创建SDK库(dll动态库)并调用SDK库(dll动态库) 一、项目场景 在日常的项目中,我们经常会遇到调用别人的数学库、线程库、图形库等操作。这些库通常就被称为SDK,SDK全称是Software Development Kit(软件开发工具包),…...
400以内的蓝牙耳机哪款好?400以内蓝牙耳机排行榜
谈起TWS,无论是传统的音频厂商还是手机厂商,都是其不可或缺的重要产品线,现在很多许多蓝牙耳机都不是千篇一律得形状,市场也鲜有商家在外观上下功夫,下面分享几款400元以内,内外兼具的耳机品牌。 一、南卡…...
基于飞桨实现的特定领域知识图谱融合方案:ERNIE-Gram文本匹配算法
文本匹配任务在自然语言处理领域中是非常重要的基础任务,一般用于研究两段文本之间的关系。文本匹配任务存在很多应用场景,如信息检索、问答系统、智能对话、文本鉴别、智能推荐、文本数据去重、文本相似度计算、自然语言推理、问答系统、信息检索等&…...
前端基础复习
1.什么叫HTML5?和原本的所说的HTML有什么区别? 本质上html和html5是一样的的。区别有: 1. 在文档类型声明上 HTML4.0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loos…...
Vue2 API-源码解析
目录 Vue.extend(option) delimiters functional Vue.component(id, Function | Object) Vue.directive( id, [definition] ) Vue.filter( id, function) Vue.nextTick() Vue.set() Vue.delete(target, index/key) Vue.compile(template) Vue.observable(object) …...
FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization
FastViT: A Fast Hybrid Vision Transformer using Structural Reparameterization 论文地址:https://arxiv.org/pdf/2303.14189.pdf 概述 本文提出了一种通用的 CNN 和 Transformer 混合的视觉基础模型 移动设备和 ImageNet 数据集上的精度相同的前提下…...
C/C++文档阅读笔记-A Simple Makefile Tutorial解析
Makefile文件可以使得程序编译变得简单。本博文并不是很系统的讲解makefile,本博文的目标是让读者快速编写自己的makefile文件并能应用到中小项目中。 简单实例 举个例子有下面3个文件,分别是hellomake.c,hellofunc.c,hellomake.…...
GraphSAGE的基础理论
文章目录GraphSAGE原理(理解用)GraphSAGE工作流程GraphSAGE的实用基础理论(编代码用)1. GraphSAGE的底层实现(pytorch)PyG中NeighorSampler实现节点维度的mini-batch GraphSAGE样例PyG中的SAGEConv实现2. …...
Windows 安装 GDAL C++库
Windows 安装 GDAL C库1. 方法1:下载配置网友编译的GDAL版本1.1 下载1.2 配置1.3 测试1.4 缺点2. 方法2:自己编译3. 参考1. 方法1:下载配置网友编译的GDAL版本 1.1 下载 CSDN: GDAL,geos联合编译的库,版本为1.8.0&am…...
二叉树基础概念
1.二叉树种类 1.1 满二叉树 满二叉树:如果一棵二叉树只有度为 0 0 0 的结点和度为 2 2 2 的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。 如图所示: 这棵二叉树为满二叉树,也可以说深度为 k k k&…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
