【忍者算法】从风扇叶片到数组轮转:探索轮转数组问题|LeetCode 189 轮转数组
从风扇叶片到数组轮转:探索轮转数组问题
生活中的算法
想象你在看一个风扇缓缓转动,每次转动三个叶片的距离。原本在上方的叶片转到了右侧,原本在右侧的叶片转到了下方...这就是一个生动的轮转过程。再比如,幼儿园老师让小朋友们围成一个圈,喊"向右移动3个位置",每个小朋友就会走到新的位置上。
这种轮转在生活中处处可见:餐厅的轮转座位安排、值班表的轮转、超市商品的轮换陈列,甚至是农田的轮作制度。它们都体现了同样的规律:保持原有顺序,整体移动特定步数。
问题描述
LeetCode第189题"轮转数组"是这样描述的:给你一个数组,将数组中的元素向右轮转 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]
最直观的解法:临时数组
就像小朋友们轮转位置时,先站到新位置再坐下。我们可以用一个临时数组记录每个元素的新位置。
让我们用一个简单的例子来理解:
原数组:[1,2,3,4], k = 2
1. 创建临时数组:[0,0,0,0]
2. 1应该移动到位置(0+2)%4=2:[0,0,1,0]
3. 2应该移动到位置(1+2)%4=3:[0,0,1,2]
4. 3应该移动到位置(2+2)%4=0:[3,0,1,2]
5. 4应该移动到位置(3+2)%4=1:[3,4,1,2]
6. 复制回原数组:[3,4,1,2]
优化解法:三次翻转
仔细观察会发现一个有趣的规律:如果我们把数组分成两部分,右边k个元素和左边其余元素,只需要三步就能完成轮转:
- 翻转整个数组
- 翻转前k个元素
- 翻转后面的元素
就像打扑克牌时的切牌技巧:先整叠反转,再分别调整两叠的顺序。
三次翻转的原理
用餐桌座位来理解:
- 所有人起立,从左到右交换位置(整体翻转)
- 前k个人调整自己的相对位置(前k个翻转)
- 剩下的人调整自己的相对位置(剩余部分翻转)
示例演示
用nums = [1,2,3,4,5], k = 2来说明:
原始数组:[1,2,3,4,5]
1. 整体翻转:
[1,2,3,4,5] -> [5,4,3,2,1]
2. 翻转前k个:
[5,4,3,2,1] -> [4,5,3,2,1]
3. 翻转剩余部分:
[4,5,3,2,1] -> [4,5,1,2,3]
Java代码实现
public void rotate(int[] nums, int k) {
if (nums == null || nums.length <= 1) {
return;
}
// 处理k大于数组长度的情况
k = k % nums.length;
if (k == 0) return;
// 1. 翻转整个数组
reverse(nums, 0, nums.length - 1);
// 2. 翻转前k个元素
reverse(nums, 0, k - 1);
// 3. 翻转剩余元素
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--;
}
}
解法比较
让我们比较这两种方法:
临时数组法:
- 时间复杂度:O(n)
- 空间复杂度:O(n)
- 优点:思路直观,易于理解
- 缺点:需要额外空间
三次翻转法:
- 时间复杂度:O(n)
- 空间复杂度:O(1)
- 优点:空间效率高,实现简单
- 缺点:思路不够直观
思考启发
这道题告诉我们:
- 有时候直观的解法不一定是最优的
- 观察数据规律很重要
- 在处理环形结构时,取余运算很有用
- 翻转操作可以用来改变元素位置关系
类似的问题还有:
- 反转字符串
- 字符串轮转
- 循环队列的实现
小结
通过轮转数组这道题,我们不仅学会了一个经典的数组操作技巧,更重要的是理解了如何通过观察数据特征,找到优雅的解决方案。记住,当遇到需要移动元素位置的问题时,考虑一下翻转操作是否能帮助我们!
作者:忍者算法
公众号:忍者算法
我准备了一份刷题清单,以及这些题目的详细题解,覆盖了绝大部分常见面试题。我可以很负责任地说,只要你把这些题真正掌握了,80%的算法面试都能遇到相似题目。公众号回复【刷题清单】获取~
【忍者算法】从风扇叶片到数组轮转:探索轮转数组问题|LeetCode 189 轮转数组的更多相关文章
- 前端与算法 leetcode 189. 旋转数组
目录 # 前端与算法 leetcode 189. 旋转数组 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 189. 旋转数组 题目描述 189. 旋转数组 概要 把他当做一到简单 ...
- LeetCode 189. 旋转数组(Rotate Array)
189. 旋转数组 LeetCode189. Rotate Array 题目描述 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6, ...
- Java实现 LeetCode 189 旋转数组
189. 旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] ...
- Leetcode 189.旋转数组 By Python
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 ...
- leetcode 189. 旋转数组(python)
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3输出: [5,6,7,1,2,3,4]解释:向右旋转 1 步: ...
- leetcode 189 旋转数组
class Solution(object): def rotate(self, nums, k): """ :type nums: List[int] :type k: ...
- [数组] Leetcode 189.旋转数组
- c++ LeetCode(初级数组篇)十一道算法例题代码详解(一)
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/10940636.html 唉!最近忙着面试找实习,然后都是面试的很多是leetcode的算法题, ...
- php 把一个数组分成有n个元素的二维数组的算法
一.第一种解法 <?php //把一个数组分成几个数组 //$arr 是数组 //$num 是数组的个数 function partition($arr,$num){ //数组的个数 $list ...
- LeetCode:删除排序数组中的重复项||【80】
LeetCode:删除排序数组中的重复项||[80] 题目描述 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原 ...
随机推荐
- 黑盒视角下的RESTful API安全测试
目录 前言 关于OWASP API TOP 10 REST API接口测试思路 接口权限测试 接口校验测试 接口滥用测试 总结 前言 RESTful API(或称RESTful Web API)在线开 ...
- 鸿蒙NEXT开发案例:亲戚关系计算器
[引言] 在快节奏的现代生活中,人们往往因为忙碌而忽略了与亲戚间的互动,特别是在春节期间,面对众多的长辈和晚辈时,很多人会感到困惑,不知道该如何正确地称呼每一位亲戚.针对这一问题,我们开发了一款基于鸿 ...
- Goland破解之无限重置(最新)
分享一下 JetBrains 全家桶 IDEA 2021.x 的激活破解教程,相当于永久激活 破解了,亲测有效,下面是详细文档哦~ JetBrains 全家桶 IDEA 2021.x 破解激活教程,相 ...
- API之接口服务
聚合数据: https://www.juhe.cn/ 百度api市场: https://apis.baidu.com/
- 用谷歌经典ML方法方法来设计生成式人工智能语言模型
上一篇:<人工智能模型学习到的知识是怎样的一种存在?> 序言:在接下来的几篇中,我们将学习如何利用 TensorFlow 来生成文本.需要注意的是,我们这里并不使用当前最热门的 Trans ...
- 启动Node.js前端项目
跟前端同事联调的时候,有时前端同事要跟其他后端同事联调,心想就自己启个前端项目,这样前端同事跟其他后端同事联调的时候,我可以先自己调来试试. 安装Node.js,NPM,NVM等,一气呵成.将前端项目 ...
- Codeforces Round 992 (Div. 2) 解题报告
比赛地址: https://codeforces.com/contest/2040 A. Game of Division 题目 https://codeforces.com/contest/2040 ...
- 推荐7个最强Appium替代工具,移动App自动化测试必备!
在移动应用开发日益火爆的今天,自动化测试成为了确保应用质量和用户体验的关键环节.Appium 作为一款广泛应用的移动应用自动化测试工具,为测试人员所熟知.然而,在不同的测试场景和需求下,还有许多其他优 ...
- 青少年学习C++参考视频
09C++选择结构(3) 第20课 初识算法 第21课 3个数排序 第22课 随机函数rand 第23课 if语句的应用 第24课 bug与debug 10C++选择结构(4) 第25课 成绩等级 第 ...
- git gitignore文件不生效
配置了 .gitigore 文件不生效,是刚开始将那些过滤的文件加到了版本控制.后续增加的,没有进入到版本控制 解决办法就是从版本控制移除,重新更新下gitignore文件 执行以下命令: 根据情况自 ...