概述
题目如下:
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:
Do it in place.Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
分析如下:
注意是要in place来完成这个问题,也就是空间复杂度是O(1)。
比较容易想到的办法是,逐步挪动,挪动N(假设数组长度为N)次之后,就完成了rotate。 但是这样可能会有的元素挪动了不止一次,有的元素完全没有动过。
例如,下面这个错误解法
从第5步开始,就和之前的步骤完全一样不会发生改变了。
//错误解法
class Solution {
public:
//(1): 1 2 3 4 5 6
//(2): 1 2 1 4 5 6
//(3): 1 2 1 4 3 6
//(4): 5 2 1 4 3 6
//(5): 5 2 1 4 3 6
//(6): 5 2 1 4 1 6
//(7): 3 2 1 4 1 6
//(8): 3 2 1 4 1 6
//(9): 形成了环
void rotate(int nums[], int n, int k) {
int start = 0;
int tmp2 = 0;
int tmp1 = nums[start];
int count = n;
while(count > 0) {
tmp2 = nums[(start + k ) % n];
nums[(start + k ) % n] = tmp1;
tmp1 = tmp2;
start = (start + k) % n;
--count;
print_list(nums, n);
}
}
};
第一种正确的做法
很神奇, 在programming pearl上有介绍到,一共有3步。假设输入数组的下标是0~ n-1,需要rotate的步数是k.
step 1 reverse原来的数组
step 2 reverse 0~ k-1
step 3 reverse k ~ n-1
我的代码:
//38ms
class Solution {
public:
void reverseString(int nums[], int start, int end) {
int i = start;
int j = end;
int temp = 0;
while (i<j) {
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
++i;
--j;
}
return;
}
void rotate(int nums[], int n, int k) {
k = k % n;
reverseString(nums, 0, n - 1);
reverseString(nums, 0, k - 1);
reverseString(nums, k, n - 1);
}
};
上面的时间复杂度是O(n),空间复杂度是O(1).
另外一个解法
一步一步地挪动,具体解答如下:
初始数组:1, 2, 3, 4, 5, 6
右移一步: 6, 1, 2, 3, 4, 5
右移二步: 5, 6, 1, 2, 3, 4
...
右移五步: 2, 3, 4, 5, 6, 1
如果k< n/2,那么就逐步向右移动 k步,否则就向左移动n - k 步。
//383ms
class Solution {
public:
void print_list(int* a, int n){
for (int i = 0; i < n; ++i) {
std::cout<<a[i]<<"t";
}
std::cout<<std::endl;
return;
}
void MoveRightByOne(int nums[], int n) {
int temp = nums[ n - 1];
for (int i = n - 1; i >=1 ; --i) {
nums[i] = nums[i - 1];
}
nums[0] = temp;
}
void MoveLeftByOne(int nums[], int n) {
int temp = nums[0];
for (int i = 0; i < n-1 ; ++i) {
nums[i] = nums[i + 1];
}
nums[n - 1] = temp;
}
void rotate(int nums[], int n, int k) {
k = k % n; // NOTE: validate input,容易漏想。
if (k < n/2) {
for (int i = 0; i < k; ++i) {
MoveRightByOne(nums, n);
}
} else {
for (int i = 0; i < n-k; ++i) {
MoveLeftByOne(nums, n);
}
}
}
};
参考资料:
//http://articles.leetcode.com/2010/04/rotating-array-in-place.html
最后
以上就是花痴冬瓜为你收集整理的LeetCode(189) Rotate Array的全部内容,希望文章能够帮你解决LeetCode(189) Rotate Array所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复