题目大意:
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.
k就是从最后一个转到第一个的次数。 如上图, k=3,就将7、6、5分别转到最左边。
1.首先是自己的答案
轮流去替换:i -> (i+k)%len 这里注意:可能轮流一轮下来,并不是每个都能替换到。比如:{1,2,3,4,5,6},k=2,这里轮流替换的为{1,3,5}、{2,4,6}才结束。因此需要一个变量来记录有没有每个都轮到num++,然后每轮的开头,分别从0,1...开始,直到每个都轮到:num==len.
class Solution { public: void swap(int& a, int& b){ a = a ^ b; b = a ^ b; a = a ^ b; } void rotate(vector<int>& nums, int k) { int len = nums.size(); if(k>=len) k = k%len; if(k == 0) return; int i = 0; int start = 0; int temp = nums[i]; i = i+k; int num = 0; while(num < len){ while(i != start){ swap(nums[i],temp); i = (i+k)%len; num++; } num++; nums[i] = temp; start++; i = start; temp = nums[i]; i = (i+k)%len; } } };
(注:以下方法是借用他人的,放在这只为自己以后能参考别人优秀代码而方便,并不是要盗取人家的知识,我在这声明,为了尊重知识产权)
Time complexity: O(n). Space complexity: O(n).
class Solution { public: void rotate(int nums[], int n, int k) { if ((n == 0) || (k <= 0)) { return; } // Make a copy of nums vector<int> numsCopy(n); for (int i = 0; i < n; i++) { numsCopy[i] = nums[i]; } // Rotate the elements. for (int i = 0; i < n; i++) { nums[(i + k)%n] = numsCopy[i]; } } };
Time complexity: O(n). Space complexity: O(1).
class Solution { public: void rotate(int nums[], int n, int k) { if ((n == 0) || (k <= 0)) { return; } int cntRotated = 0; int start = 0; int curr = 0; int numToBeRotated = nums[0]; int tmp = 0; // Keep rotating the elements until we have rotated n // different elements. while (cntRotated < n) { do { tmp = nums[(curr + k)%n]; nums[(curr+k)%n] = numToBeRotated; numToBeRotated = tmp; curr = (curr + k)%n; cntRotated++; } while (curr != start); // Stop rotating the elements when we finish one cycle, // i.e., we return to start. // Move to next element to start a new cycle. start++; curr = start; numToBeRotated = nums[curr]; } } };
Time complexity: O(n). Space complexity: O(1).
class Solution { public: void rotate(int nums[], int n, int k) { k = k%n; // Reverse the first n - k numbers. // Index i (0 <= i < n - k) becomes n - k - i. reverse(nums, nums + n - k); // Reverse tha last k numbers. // Index n - k + i (0 <= i < k) becomes n - i. reverse(nums + n - k, nums + n); // Reverse all the numbers. // Index i (0 <= i < n - k) becomes n - (n - k - i) = i + k. // Index n - k + i (0 <= i < k) becomes n - (n - i) = i. reverse(nums, nums + n); } };
Time complexity: O(n). Space complexity: O(1).
class Solution { public: void rotate(vector<int>& nums, int k) { int n = nums.size(); if (k%n == 0) return; int first = 0, middle = n-k%n, last = n; int next = middle; while(first != next) { swap (nums[first++], nums[next++]); if (next == last) next = middle; else if (first == middle) middle = next; } } };
Time complexity: O(n). Space complexity: O(1).
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; } } } };