Leetcode经典题5--轮转数组

题目描述

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

输入输出示例 :

输入: nums = [1,2,3,4,5,6,7], k = 3

输出: [5,6,7,1,2,3,4]

解释:

向右轮转 1 步: [7,1,2,3,4,5,6]

向右轮转 2 步: [6,7,1,2,3,4,5]

向右轮转 3 步: [5,6,7,1,2,3,4]

解题方案

模除操作

方式一:使用额外的数组

算法思想

使用额外的数组来将每个元素放至正确的位置。用 n 表示数组的长度,我们遍历原数组,将原数组下标为 i 的元素放至新数组下标为 (i+k) mod n 的位置,最后将新数组拷贝至原数组即可

实现代码

class Solution {public void rotate(int[] nums, int k) {//获取数组长度int n = nums.length;//创建一个新数组int[] newArr = new int[n];//遍历原数组,将数组放到正确的位置for (int i = 0; i < n; ++i) {newArr[(i + k) % n] = nums[i];}System.arraycopy(newArr, 0, nums, 0, n);}
}

复杂度分析

  • 时间复杂度: O(n),其中 n 为数组的长度。
  • 空间复杂度: O(n)。
方法二:环状替换

算法思想:

为了防止元素覆盖的问题,因此,从另一个角度,我们可以将被替换的元素保存在变量 temp 中,从而避免了额外数组的开销。

我们用下面的例子更具体地说明这个过程:

nums = [1, 2, 3, 4, 5, 6]

k = 2

 

  • 我们从位置 0 开始,最初令 temp=nums[0]。
  • 根据规则,位置 0 的元素会放至 (0+k) mod n 的位置,令 x=(0+k) mod n,此时交换 temp 和 nums[x],完成位置 x 的更新。
  • 然后,我们考察位置 x,并交换 temp 和 nums [(x+k) mod n],从而完成下一个位置的更新。不断进行上述过程,直至回到初始位置 0。每次都考察要更新的位置

容易发现,当回到初始位置 0 时,有些数字可能还没有遍历到,此时我们应该从下一个数字开始重复的过程

怎么才算遍历结束呢?

我们不妨先考虑这样一个问题:从 0 开始不断遍历,最终回到起点 0 的过程中,我们遍历了多少个元素?

由于最终回到了起点,故该过程恰好走了整数数量的圈,不妨设为 a 圈;

再设该过程总共遍历了 b 个元素。

我们用总元素数b 除以 每圈遍历的元素个数n/k 会得到总共遍历的圈数a

因此,我们有 an=bk,即 an 一定为 n,k 的公倍数。又因为我们在第一次回到起点时就结束,因此 a 要尽可能小,故 an 就是 n,k 的最小公倍数 lcm(n,k),因此 b 就为 lcm(n,k)/k。

这说明单次遍历会访问到 lcm(n,k)/k 个元素。为了访问到所有的元素,我们需要进行遍历的次数为

其中 gcd 指的是最大公约数。

实现代码

使用单独的变量 count 跟踪当前已经访问的元素数量,当 count=n 时,结束遍历过程。

class Solution {public void rotate(int[] nums, int k) {//数组长度int n = nums.length;k = k % n;//遍历次数 k和n的最大公约数int count = gcd(k, n);//循环遍历for (int start = 0; start < count; ++start) {//当前遍历的数组下标int current = start;//开始时的数组元素int prev = nums[start];do {//将要更新的数组下标int next = (current + k) % n;//将被覆盖的数组值赋给tempint temp = nums[next];//更新nums[next] = prev;prev = temp;current = next;} while (start != current);}}public int gcd(int x, int y) {return y > 0 ? gcd(y, x % y) : x;}
}

复杂度分析

时间复杂度:O(n),其中 n 为数组的长度。每个元素只会被遍历一次。

空间复杂度:O(1)。我们只需常数空间存放若干变量。

方法三:数组翻转

算法思想

该方法基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 k mod n 个元素会移动至数组头部,其余元素向后移动 k mod n 个位置。

实现步骤

  • 我们可以先将所有元素翻转,这样尾部的 k mod n 个元素就被移至数组头部,
  • 然后我们再翻转 [0,kmodn−1] 区间的元素和 [kmodn,n−1] 区间的元素即能得到最后的答案。

我们以 n=7,k=3 为例进行如下展示:

实现代码

class Solution {public void rotate(int[] nums, int k) {//确定分开反转的位置k %= nums.length;//反转整个数组reverse(nums, 0, nums.length - 1);//反转前一半reverse(nums, 0, k - 1);//反转后一半reverse(nums, k, nums.length - 1);}//数组翻转public void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start] = nums[end];nums[end] = temp;start += 1;end -= 1;}}
}

复杂度分析

时间复杂度:O(n),其中 n 为数组的长度。每个元素被翻转两次,一共 n 个元素,因此总时间复杂度为 O(2n)=O(n)。

空间复杂度:O(1)。

欢迎大家点赞,评论加关注呦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/484866.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac port 安装redis 并设置为系统服务 自定义配置方法

mac系统中&#xff0c;port 包管理工具比brew的速度快N倍&#xff0c;今天就给大家分享一下在macos系统中如何使用 port安装 redis数据库并配置为服务自动启动和自定义redis.conf配置的方法。 1. 安装redis sudo port install redis 2. 启动redis服务 sudo port load redis …

github仓库自动同步到gitee

Github Actions是Github推出的自动化CI/CD的功能&#xff0c;我们将使用Github Actions让Github仓库同步到Gitee 同步的原理是利用 SSH 公私钥配对的方式拉取 Github 仓库的代码并推送到 Gitee 仓库中&#xff0c;所以我们需要以下几个步骤 生成 SSH 公私钥添加公钥添加私钥配…

工业—使用Flink处理Kafka中的数据_ProduceRecord2

使用 Flink 消费 Kafka 中 ProduceRecord 主题的数据,统计在已经检验的产品中,各设备每 5 分钟 生产产品总数,将结果存入HBase 中的 gyflinkresult:Produce5minAgg 表, rowkey“

人工智能学习用的电脑安装cuda、torch、conda等软件,版本的选择以及多版本切换

接触人工智能的学习三个月了&#xff0c;每天与各种安装包作斗争&#xff0c;缺少依赖包、版本高了、版本低了、不兼容了、系统做一半从头再来了。。。这些都是常态。三个月把单位几台电脑折腾了不下几十次安装&#xff0c;是时候总结一下踩过的坑和积累的经验了。 以一个典型的…

MongoDB整合SpringBoot

MongoDB整合SpringBoot 环境准备 1.引入依赖 <!--spring data mongodb--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 2.配置yml spr…

【Calibre-Web】Calibre-Web服务器安装详细步骤(个人搭建自用的电子书网站,docker-compose安装)

文章目录 一、Calibre-Web和Calibre的区别是什么&#xff1f;使用场景分别是什么&#xff1f;二、服务器安装docker和docker-compose三、服务器安装Calibre-Web步骤1、安装完成后的目录结构2、安装步骤3、初始配置4、启动上传 四、安装Calibre五、docker-compose常用命令六、客…

人工智能驱动的骗局会模仿熟悉的声音

由于人工智能技术的进步&#xff0c;各种现代骗局变得越来越复杂。 这些骗局现在包括人工智能驱动的网络钓鱼技术&#xff0c;即使用人工智能模仿家人或朋友的声音和视频。 诈骗者使用来自社交媒体的内容来制作深度伪造内容&#xff0c;要求提供金钱或个人信息。个人应该通过…

【QT】一个简单的串口通信小工具(QSerialPort实现)

目录 0.简介 1.展示结果 1&#xff09;UI界面&#xff1a; 2&#xff09;SSCOM&#xff08;模拟下位机收发&#xff09;&#xff1a; 3&#xff09;VSPD虚拟串口驱动&#xff08;连接上位机和下位机的串口&#xff09;&#xff1a; 4&#xff09;实际收发消息效果及视频演…

python语法基础---正则表达式(补充)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 上一篇文章中&#xff0c;我们讲到了贪婪匹配和非贪婪匹配&#xff0c;我们在这篇文章中&#xff0c;主要讲的就是贪婪匹配和非贪婪匹配的剩下的部分&#xff0c;话不多说&#x…

Elasticsearch数据迁移(快照)

1. 数据条件 一台原始es服务器&#xff08;192.168.xx.xx&#xff09;&#xff0c;数据迁移后的目标服务器&#xff08;10.2.xx.xx&#xff09;。 2台服务器所处环境&#xff1a; centos7操作系统&#xff0c; elasticsearch-7.3.0。 2. 为原始es服务器数据创建快照 修改elas…

golang实现单例日志对象

原文地址&#xff1a;golang实现单例日志对象 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 介绍 golang有很多日志包&#xff0c;通过设置和修改都能实现日志轮转和自定义日志格式。例如&#xff1a;log、zap、golog、slog、log4go 等等。 …

7. 一分钟读懂“单例模式”

7.1 模式介绍 单例模式就像公司里的 打印机队列管理系统&#xff0c;无论有多少员工提交打印任务&#xff0c;大家的请求都汇总到唯一的打印管理中心&#xff0c;按顺序排队输出。这个中心必须全局唯一&#xff0c;避免多个队列出现资源冲突&#xff0c;保证打印任务井然有序。…

【AI系统】布局转换原理与算法

布局转换原理与算法 数据布局转换目前已经越来越多地用于编译器的前端优化&#xff0c;将内部数据布局转换为后端设备友好的形式。数据布局转换主要影响程序的空间局部性&#xff0c;所谓空间局部性指的是如果一个内存位置被引用了一次&#xff0c;那么程序很可能在不远的将来…

GPS周和周内秒 UTC时 格林尼治时间

1.GPS周和周内秒介绍 GPS周和周内秒是全球定位系统&#xff08;GPS&#xff09;中用于时间表示的两个重要概念&#xff0c;它们共同构成了GPS时间系统。以下是对这两个概念的详细介绍&#xff1a; GPS周&#xff08;GPS Week&#xff09; GPS周是GPS系统内部所采用的时间单位…

Java-异常处理机制-try-catch

Java-异常处理机制 一、异常概述1、异常的抛出机制2、如何对待异常3、异常的体系结构3.1、Throwable3.2、Error和Exception3.3、编译时异常和运行时异常3.4、常见的异常有哪些&#xff1f; 二、异常的处理方式一 try-catch的使用1、过程1&#xff1a;抛2、过程2&#xff1a;抓3…

在Ubuntu22.04.5上安装Docker-CE

文章目录 1. 查看Ubuntu版本2. 安装Docker-CE2.1 安装必要的系统工具2.2 信任Docker的GPG公钥2.3 写入软件源信息2.4 安装Docker相关组件2.5 安装指定版本Docker-CE2.5.1 查找Docker-CE的版本2.5.2 安装指定版本Docker-CE 3. 启动与使用Docker3.1 启动Docker服务3.2 查看Docker…

【趋势红蓝交易】主图指标操盘技术图文展示,注意要点,通达信炒股软件指标

如上图&#xff0c;主图指标【趋势红蓝交易】&#xff0c;蓝色线下空头趋势&#xff0c;不进场操作或只做超短线的反弹行情。红线之上多头行情&#xff0c;顺势做多&#xff0c;波段和趋势多头操作。 多空操作区间K线变色功能&#xff0c;上涨区间红色K线&#xff0c;叠加紫色趋…

网络协议(TCP/IP模型)

目录 网络初识 网络协议 协议分层 协议拆分 分层 协议分层的优势 1.封装效果 2.解耦合 TCP/IP五层模型 协议之间配合工作&#xff08;详解&#xff09; 网络初识 网络核心概念&#xff1a; 局域网&#xff1a;若干电脑连接在一起&#xff0c;通过路由器进行组网。 …

基于图和个性化PageRank的RAG方法HippoRAG

HippoRAG是2024年5月的一篇论文《HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models》(github)&#xff0c;它受人脑长期记忆的启发(Hippo是海马体英文单词的前缀)&#xff0c;用知识图谱(KG)来存储知识&#xff0c;并用检索编码器和个性化Pag…

【电子设计】WifiESP8266无线通信

硬件 野火STM32开发板 操作系统 FreeRTOS 软件Keil5野火蓝牙模块 ESP8266模块 1. ESP8266 简介 ESP8266 是串口型 WIFI&#xff0c;速度比较低&#xff0c;不能用来传输图像或者视频这些大容量的数据&#xff0c;主要应用于数据量传输比较少的场合&#xff0c;比如温湿度…