説明
配列が与えられたら、配列の要素をkの位置から右に移動します。ここで、kは非負の数です。
例1:
入力:[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:
入力:[-1、-100,3,99]およびk = 2
出力:[3,99、-1、-100]
説明:
右への回転ステップ1:[99、-1、-100,3]
右に2ステップ回転するには:[3,99、-1、-100]
説明:
できるだけ多くの解決策を考えてください。この問題を解決するには、少なくとも3つの異なる方法があります。
スペースの複雑さがO(1)のインプレースアルゴリズムを使用する必要があります。
ソース:LeetCode
リンク:https://leetcode-cn.com/problems/rotate-array/
解決する
// 最大公约数,最小公倍数
template<typename T>
T gcd(T a, T b) {
while (a % b != 0) {
T c = a % b;
a = b;
b = c;
}
return b;
}
template<typename T>
T lcm(T a, T b) {
return a * b / gcd(a, b);
}
class Solution {
public:
// 方法一,原地交换实现原始版,空间复杂度O(N)原始版
void rotate_1(vector<int> &nums, int k) {
const int N = nums.size();
if (N < 2 || (k % N == 0)) {
// 少于2个元素或者翻转k是元素个数的倍数,不做任何动作
return;
}
int n = gcd(N, k);
for (int i = 0; i < n; ++i) {
int start = i;
int curPos = i;
int pre = nums[curPos];
int next = 0;
do {
int nextPos = (curPos + k) % N;
next = nums[nextPos];
nums[nextPos] = pre;
pre = next;
curPos = nextPos;
} while (curPos != start);
}
}
// 方法一优化版,原地交换实现代码优化版,空间复杂度O(N)原始版
void rotate_2(vector<int> &nums, int k) {
const int N = nums.size();
if (N < 2 || (k % N == 0)) {
// 少于2个元素或者翻转k是元素个数的倍数,不做任何动作
return;
}
int n = gcd(N, k);
for (int i = 0; i < n; ++i) {
int prev = nums[i];
int curPos = i;
do {
int nextPos = (curPos + k) % N;
// 通过每次的元素交换,将当前被覆盖的位置(nextPos)元素保存到prev中,待下次交换使用
std::swap(nums[nextPos], prev);
curPos = nextPos;
} while (curPos != i);
}
}
// 方法二,采用辅助数组空间
void rotate_usespace(vector<int> &nums, int k) {
const int N = nums.size();
if (N < 2 || (k % N == 0)) {
// 少于2个元素或者翻转k是元素个数的倍数,不做任何动作
return;
}
vector<int> record(N, 0);
for (int i = 0; i < N; ++i) {
int changePos = (i + k) % N;
record[changePos] = nums[i];
}
nums.assign(record.begin(), record.end());
}
// 方法三,采用STL算法实现
void rotate(vector<int> &nums, int k) {
const int N = nums.size();
if (N < 2 || (k % N == 0)) {
// 少于2个元素或者翻转k是元素个数的倍数,不做任何动作
return;
}
k = k % N; // 处理k > N的场景
std::rotate(nums.begin(), nums.begin() + (N - k), nums.end());
}
};