题目:
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7]
is rotated to [5,6,7,1,2,3,4]
.
Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Could you do it in-place with O(1) extra space?
Related problem: Reverse Words in a String II
题意:
从给定的第K个位置翻转数组。
思路一:
将数组复制一份,之后将复制的数组从第K个位置一次放回到原数组中。
代码:
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
vector<int> result(n);
if(n==0 || k<=0){
return;
}
for(int i=0; i<n; i++){
result[i] = nums[i];
}
for(int i=0; i<n; i++){
nums[(i+k)%n] = result[i]; //(i+k)%n相当于产生数组“环”
}
}
};
思路二:
一个数字一个数字的交换。
代码:
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
if(n==0 || k<=0){
return;
}
int cur = 0;
int tmp = 0;
int numRotated = nums[0];
int count = 0;
int start = 0;
while(count<n){
do{
tmp = nums[(cur+k)%n];
nums[(cur+k)%n] = numRotated;
numRotated = tmp;
cur = (cur+k)%n;
count++;
}while(cur!=start);
start++;
cur = start;
numRotated = nums[cur];
}
}
};
思路三:
先将前n-k个元素翻转,再讲n-k到n个元素翻转,之后将全部n个元素翻转
4 3 2 1 7 6 5 =》 5 6 7 1 2 3 4
代码:
class Solution {
public:
void rotate(vector<int>& nums, int k) {
int n = nums.size();
k = k%n;
reverse(nums.begin(), nums.begin()+n-k);
reverse(nums.begin()+n-k, nums.end());
reverse(nums.begin(), nums.end());
}
};
public class Solution {
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n;
reverse(nums, 0, n-k-1);
reverse(nums, n-k, n-1);
reverse(nums, 0, n-1);
}
public void reverse(int[] nums, int start, int end){
while(start<end){
int tmp = nums[start];
nums[start] = nums[end];
nums[end] = tmp;
start++;
end--;
}
}
}
思路四:
先将最后k个元素与前k个元素交换,之后前半部分有序,处理后半部分即可
5 6 7 4 1 2 3
class Solution
{
public:
void rotate(int nums[], int n, int k)
{
for (; k = k%n; n -= k, nums += k)
{
// Swap the last k elements with the first k elements.
// The last k elements will be in the correct positions
// but we need to rotate the remaining (n - k) elements
// to the right by k steps.
for (int i = 0; i < k; i++)
{
swap(nums[i], nums[n - k + i]);
}
}
}
};
思路五:
同样分成两个子串,之后对部分处理。
1 5 6 7 2 3 4
class Solution
{
public:
void rotate(int nums[], int n, int k)
{
if ((n == 0) || (k <= 0) || (k%n == 0))
{
return;
}
k = k%n;
// Rotation to the right by k steps is equivalent to swapping
// the two subarrays nums[0,...,n - k - 1] and nums[n - k,...,n - 1].
int start = 0;
int tmp = 0;
while (k > 0)
{
if (n - k >= k)
{
// The left subarray with size n - k is longer than
// the right subarray with size k. Exchange
// nums[n - 2*k,...,n - k - 1] with nums[n - k,...,n - 1].
for (int i = 0; i < k; i++)
{
tmp = nums[start + n - 2*k + i];
nums[start + n - 2*k + i] = nums[start + n - k + i];
nums[start + n - k + i] = tmp;
}
// nums[n - 2*k,...,n - k - 1] are in their correct positions now.
// Need to rotate the elements of nums[0,...,n - k - 1] to the right
// by k%n steps.
n = n - k;
k = k%n;
}
else
{
// The left subarray with size n - k is shorter than
// the right subarray with size k. Exchange
// nums[0,...,n - k - 1] with nums[n - k,...,2*(n - k) - 1].
for (int i = 0; i < n - k; i++)
{
tmp = nums[start + i];
nums[start + i] = nums[start + n - k + i];
nums[start + n - k + i] = tmp;
}
// nums[n - k,...,2*(n - k) - 1] are in their correct positions now.
// Need to rotate the elements of nums[n - k,...,n - 1] to the right
// by k - (n - k) steps.
tmp = n - k;
n = k;
k -= tmp;
start += tmp;
}
}
}
};
转载链接:https://leetcode.com/discuss/27387/summary-of-c-solutions