环状替换法详解

环状替换法详解

给定一个整数数组 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也是整数。

那么

ank=b

注意:a是整数,b也是整数.

但是!注意了轰!n/k不一定是整数.

ankaa=kgcd(k,n)

kgcd(k,n)n=gcd(k,n)m,k=gcd(k,n)h

nkmh,mha=h=kgcd(k,n)

所以:

nb=nank=gcd(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);
}
};
posted @   Kellen_Gram  阅读(197)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示