Rotate Array
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.
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Hint:
Could you do it in-place with O(1) extra space?
Analysis:
1st solution is to use a temp array. Space O(n).e.g. nums = [ 1 2 3 4 5 ], k=2
temp = [4 5 1 2 3]
num = temp
2nd solution is to rotate one position each time and do it k times. Space O(1), but it will exceed the time limit.
e.g. nums = [1 2 3 4 5], k=2
1st iteration:
nums = [1 1 2 3 4] temp = 5, then nums = [5 1 2 3 4]
2nd iteration:
nums = [5 5 1 2 3] temp = 4, nums = [4 5 1 2 3]
3rd solution is to rotate k steps once for an element. Space O(1).
e.g. nums = [1 2 3 4 5 6], k=2
1st iteration: starts from nums[i=0], keep rotate nums[i+k] until meet the start position
nums = [5 2 1 4 3 6]
2nd iteration: starts from nums[i=1]
nums = [5 6 1 2 3 4]
How to determine the number of iterations?
Use the gcd (greatest common divisor) between n and k. Because we need to find how many "circles" are there in the sequence, one circle is like counting each element nums[i] + k + k + k... and back to nums[i]. If the gcd is 1, which means only one circle will cover all the elements in the sequence, so only 1 iteration is needed.If the gcd is 2, there are 2 circles, so 2 iterations are needed.
Code(C++):
class Solution {
public:
int gcd(int a, int b){
if (b==0){
return a;
}else{
return gcd(b, a%b);
}
}
void rotate(int nums[], int n, int k) {
int i,j,tmp,pre;
k = k%n;
for (int i=0;i<gcd(n,k);i++){
pre = nums[i];
j=i;
while ((j+k)%n != i){
tmp = nums[(j+k)%n];
nums[(j+k)%n] = pre;
pre = tmp;
j = (j+k)%n;
}
nums[(j+k)%n] = pre;
}
}
};
Code(Python):
class Solution:
# @param nums, a list of integer
# @param k, num of steps
# @return nothing, please modify the nums list in-place.
def rotate(self, nums, k):
def gcd(a,b):
if b==0:
return a
else:
return gcd(b, a%b)
n = len(nums)
for i in range(gcd(n,k)):
pre = nums[i]
j = i
while (j+k)%n != i:
nums[(j+k)%n], pre = pre, nums[(j+k)%n]
j = (j+k)%n
nums[(j+k)%n] = pre
No comments:
Post a Comment