环状替换法详解
环状替换法详解
给定一个整数数组 nums
,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
链接:https://leetcode.cn/problems/rotate-array
示例:
输入: 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.在官方解答中给出了环装替换法,不易理解,现给出推导:
⭐ 该方法实质可以理解为:
一个圆形桌子上吃饭,每个人想吃的菜不同,就移一下位置。(假设桌子不能转哈)
一共有n个人,要往自己的左手边移动k个位置坐。
ex1:
对于其中一个元素 x ,间隔k回到自己要走a圈,a为整数;
要么一圈经过个元素呢? n/k个,对吧.(在这个n/k不一定是整数,但是实际要数那么个数就是向下取整)
例如图1:从0开始,间隔3经过了 3和6 。个数为7/3,取整为2
假设x回到自己身上一共经过b个元素,b也是整数。
那么
注意:a是整数,b也是整数.
但是!注意了轰!n/k不一定是整数.
所以:
所以遍历次数gcd(n,k)
2.C++代码如下
class Solution { public: void rotate(vector<int>& nums, int k) { if (k == 0) return; int N = nums.size(); k = k % N; int j; int Num = gcd(N, k); for (int i = 0; i < Num; ++i) { j = i; //记录起点 do { j = (j + k) % N; Swap(nums[i], nums[j]); } while (j !=i ); //判断有没有回到原来的位置 } } void Swap(int& x, int& y) { int temp = x; x = y; y = temp; } //求最大公约数 int gcd(int a, int b) { int temp; if (a < b) Swap(a, b); while (b>0) { temp = a % b; a = b; b = temp; } return a; } };
比如图1:0-3-6-2-5-1-4-0
其实就是每次进行交换,0号说我要坐3号位置,那么3号说我让给你你吧,我先坐0号。
但是3号自己也要动,所以3号又从0号坐到了6号
🍰 每次nums[i]存储的都是下一次要交换的人
3.为啥求个数呢?
对于这种情况,n=4,k=2,只遍历一次是行不通的
4.其他方法
4.1 先记录要轮转的元素,再移动
class Solution { public: void rotate(vector<int>& nums, int k) { if (k == 0) return; int N = nums.size(); k=k%N; vector<int>temp(nums.begin() + N - k, nums.end()); int i = N - 1; for (; i >= k; --i) nums[i] = nums[i - k]; for (i = 0; i < k; ++i) nums[i] = temp[i]; } };
4.2 先总的进行一次翻转,再左右翻转
class Solution { public: void reverse(vector<int>& nums, int start, int end) { while (start < end) { swap(nums[start], nums[end]); start += 1; end -= 1; } } void rotate(vector<int>& nums, int k) { k %= nums.size(); reverse(nums, 0, nums.size() - 1); reverse(nums, 0, k - 1); reverse(nums, k, nums.size() - 1); } };
合集:
LeetCode算法初级
分类:
LeetCode初级算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话