轮转数组[中等]
优质博文:IT-BLOG-CN
一、题目
给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。
示例 1:
输入: 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]
示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
进阶: 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。你可以使用空间复杂度为O(1)的原地算法解决这个问题。
二、代码
【1】使用额外的数组: 我们可以使用额外的数组来将每个元素放至正确的位置。我们遍历原数组,将原数组下标为i的元素放至新数组下标为(i+k) mod nums.length的位置,最后将新数组拷贝至原数组即可。
class Solution {public void rotate(int[] nums, int k) {// 使用一个等长的数组int[] newArray = new int[nums.length];for (int i = 0; i < nums.length; i++) {newArray[(i + k) % nums.length] = nums[i];}System.arraycopy(newArray, 0, nums, 0, nums.length);}
}
时间复杂度: O(n)其中n为数组的长度。
空间复杂度: O(n)
【2】数组翻转: 该方法基于如下的事实:当我们将数组的元素向右移动k次后,尾部k mod n个元素会移动至数组头部,其余元素向后移动k mod n个位置。
该方法为数组的翻转: 我们可以先将所有元素翻转,这样尾部的k mod n个元素就被移至数组头部,然后我们再翻转[0,k mod n−1]区间的元素和[k mod n,n−1]区间的元素即能得到最后的答案。
我们以n=7,k=3为例进行如下展示:
| 操作 | 结果 |
|---|---|
| 原始数组 | 1 2 3 4 5 6 7 |
| 翻转所有元素 | 7 6 5 4 3 2 1 |
翻转[0,k mod n−1]区间的元素 | 5 6 7 4 3 2 1 |
翻转 [k mod n,n−1]区间的元素 | 5 6 7 1 2 3 4 |
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);}private void reverse(int[] nums, int start, int end) {while(start < end) {int temp = nums[start];nums[start] = nums[end];nums[end] = temp;++start;--end;}}
}
【3】环状替换: 方法一中使用额外数组的原因在于如果我们直接将每个数字放至它最后的位置,这样被放置位置的元素会被覆盖从而丢失。因此,从另一个角度,我们可以将被替换的元素保存在变量temp中,从而避免了额外数组的开销。
我们从位置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个元素。因此,我们有an=bk,即an一定为n,k的公倍数。又因为我们在第一次回到起点时就结束,因此a要尽可能小,故an就是n,k的最小公倍数lcm(n,k),因此b就为lcm(n,k)/k。
这说明单次遍历会访问到lcm(n,k)/k个元素。为了访问到所有的元素,我们需要进行遍历的次数为n/(lcm(n,k)/k)=nk/(lcm(n,k))=gcd(n,k)
其中
gcd指的是最大公约数。
我们用下面的例子更具体地说明这个过程:
nums = [1, 2, 3, 4, 5, 6]
k = 2

如果读者对上面的数学推导的理解有一定困难,也可以使用另外一种方式完成代码:使用单独的变量count跟踪当前已经访问的元素数量,当count=n时,结束遍历过程。
class Solution {public void rotate(int[] nums, int k) {int n = nums.length;k = 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;int 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)我们只需常数空间存放若干变量。
相关文章:
轮转数组[中等]
优质博文:IT-BLOG-CN 一、题目 给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。 示例 1: 输入: 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,…...
【SpringBoot系列】自动装配的魅力:Spring Boot vs 传统Spring
IT行业有哪些证书含金量高? 文章目录 IT行业有哪些证书含金量高?强烈推荐前言区别项目配置:依赖管理:内嵌服务器:开发体验: 实例Spring项目示例:Spring Boot项目示例: 总结强烈推荐专栏集锦写在最后 强烈…...
idea自动生成实体类
第一步:idea连接数据库 出现这个就连接成功 第二步:选择数据库 第三步:创建实体类 也可以点击数据库一下子全部创建 选择创建实体类所放位置 这样就完成了,点击看看对其做相应修改...
uniapp -- picker民族选择器
目录 一、实现思路 二、实现步骤 ①view部分展示 ② JavaScript 内容 ③css中样式展示 三、效果展示...
生信学习笔记1:学习如何用OPLS-DA分析代谢组数据(从入门到掌握)
偏最小二乘法(PLS)和正交偏最小二乘法(OPLS)是统计模型,用于寻找两组数据矩阵之间的关系。它们广泛应用于化学计量学、生物信息学、经济预测等领域。 偏最小二乘法(PLS) 偏最小二乘法是一种多变量分析方法,主要用于找到两组数据(通常是预测变量集和响应变量集)之间…...
CDR2024最新版本怎么下载?Coreldraw相关快捷键教程分享
想必从事平面设计的大咖们都知道,Coreldraw是一款优秀的图形设计软件,被广泛地运用在平面设计、包装设计、服装设计各个生活领域,因此了解一些关于CorelDRAW快捷键的知识是很有必要的。因为使用快捷键不仅使用起来方便快捷,而且提…...
C语言实战项目<贪吃蛇>
我们这篇会使用C语言在Windows环境的控制台中模拟实现经典小游戏贪吃蛇 实现基本的功能: 结果如下: 1.一些Win32 API知识 本次实现呢我们会用到一些Win32 API的知识(WIN32 API也就是Microsoft Windows 32位平台的应用程序编程接口): 1)控制窗口大小 我们可以使用…...
人工智能时代:AI提示工程的奥秘 —— 驾驭大语言模型的秘密武器
文章目录 一、引言二、提示工程与大语言模型三、大语言模型的应用实践四、策略与技巧五、结语《AI提示工程实战:从零开始利用提示工程学习应用大语言模型》亮点内容简介作者简介目录获取方式 一、引言 随着人工智能技术的飞速发展,大语言模型作为一种新…...
Idea编写mapper.xml文件提示表名和字段
一、连接database 二、setting- > language -> sql Dialects中 的选项设为 mysql就可以了 三、测试...
解密人工智能:探索机器学习奥秘
🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 机器学习的定义二. 机器学习的发展历程三. 机器学习的原理四. 机器学习的分类…...
C语言第十四弹---函数递归
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 函数递归 1、递归是什么? 1.1、递归的思想 1.2、递归的限制条件 2、递归举例 2.1、举例1:求n的阶乘 2.1.1、分析和代码实现 2.1.2、…...
etcd自动化安装配置教程
文章目录 前言一、简介1. 简介2. 特点3. 端口介绍 二、etcd安装教程(单机版)1. 复制脚本2. 增加执行权限3. 执行脚本4. 查看启动状态5. 卸载etcd 三、etcd安装教程(集群版)1. 复制脚本2. 增加执行权限3. 分发脚本4. 执行脚本5. 启…...
时间序列预测——GRU模型
时间序列预测——GRU模型 在深度学习领域,循环神经网络(RNN)是处理时间序列数据的一种常见选择。上期已介绍了LSTM的单步和多步预测。本文将深入介绍一种LSTM变体——门控循环单元(GRU)模型,包括其理论基础…...
通用CI/CD软件平台TeamCity全新发布v2023.11——增强Git托管平台的集成
TeamCity是一个通用的 CI/CD 软件平台,可以实现灵活的工作流、协作和开发做法。我们的解决方案将帮助在您的 DevOps 流程中成功实现持续集成、持续交付和持续部署。 TeamCity 2023.11正式版下载 TeamCity 2023.11 带来了矩阵构建和构建缓存等多项备受期待的功能&a…...
C语言:register类型变量
register—— 寄存器存储 register 是 C 语言中的一种存储类别(Storage Class),它用于告诉编译器将变量存储在寄存器中。在 C 语言中,变量的存储位置可以是寄存器、堆栈或静态存储区,使用 register 存储类别可以帮助我…...
android 自定义下拉框
一、 简介: 原生Android 提供的spinner下拉框不怎么方便,样式有点丑。修改起来麻烦,于是就自己动手写了一下拉列表。 实现原理使用的是,popwindow弹框,可实现宽高自定义,下拉列表使用listview. 二、pop弹框…...
揭开时间序列的神秘面纱:特征工程的力量
目录 写在开头1. 什么是特征工程?1.1 特征工程的定义和基本概念1.2 特征工程在传统机器学习中的应用1.3 时间序列领域中特征工程的独特挑战和需求3. 时间序列数据的特征工程技术2.1 数据清洗和预处理2.1.1 缺失值处理2.1.2 异常值检测与处理2.2 时间特征的提取2.2.1 时间戳解析…...
vue3 源码解析(5)— patch 函数源码的实现
什么是 patch 在 vue 中 patch 函数的作用是在渲染的过程中,比较新旧节点的变化,通过打补丁的形式,进行新增、删除、移动或替换操作,此过程避免了大量的 dom 操作,提升了运行的性能。 patch 执行流程 patch 函数整体…...
蓝桥杯2024/1/28----十二届省赛题笔记
题目要求: 2、 竞赛板配置要求 2.1将 IAP15F2K61S2 单片机内部振荡器频率设定为 12MHz。 2.2键盘工作模式跳线 J5 配置为 KBD 键盘模式。 2.3扩展方式跳线 J13 配置为 IO 模式。 2.4 请注意 : 选手需严格按照以上要求配置竞赛板,编写和调…...
STM32+ESP8266 实现物联网设备节点
目录 一、硬件准备 二、编译环境 三、源代码地址 四、说明 五、测试方法 六、所有测试工具和文档 本项目使用stm32F103ZEesp8266实现一个物联网的通信节点,目前支持的协议有mqtt,tcp。后续会持续更新,增加JSON,传感器&#…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
WEB3全栈开发——面试专业技能点P4数据库
一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await…...
C++ 类基础:封装、继承、多态与多线程模板实现
前言 C 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类…...
