題目描述
給定一個數組,將數組中的元素向右移動 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]
答案
解法一:
如果不要求空間複雜度爲O(1)的話,可以利用一個輔助數組(把數組的變化看成兩部分,左邊的部分右移,右邊的部分左移)
時間複雜度O(n),空間複雜度O(n)
代碼如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
//left存需要往右移的左半部分數組
int[] left = Arrays.copyOfRange(nums,0,nums.length-k);
for(int i=0;i<k;i++){
nums[i] = nums[i+nums.length-k];
}
for(int i=k;i<nums.length;i++){
nums[i] = left[i-k];
}
return;
}
}
解法二
將數組旋轉k次,每次旋轉1個位置
時間複雜度O(n*k),空間複雜度O(1)
代碼如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
while(k>0){
rotateForOne(nums);
k--;
}
}
private void rotateForOne(int[] nums){
int pre = nums[0];
for(int i=1;i<nums.length;i++){
int temp = nums[i];
nums[i] = pre;
pre = temp;
}
nums[0] = pre;
}
}
解法三
直接把元素放到它最後應該在的位置(我們需要把被替換的數字保存在變量 temp 裏面。然後,我們將被替換數字temp放到它正確的位置,並繼續這個過程 n次)。這有個問題就是可能在沒有遍歷所有數字的情況下回到出發數字,這就需要加一個判斷,如果出現這個情況,就從下一個數字開始,重複上述過程,直到數組中的所有元素都被移動。
時間複雜度O(n),空間複雜度O(1)
代碼如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
int count = 0;//移動的次數,當count==nums.length時,移動結束
for(int i=0;count<nums.length;i++){
int current = i;
int pre = nums[i];
do{
current = (current+k)%nums.length;
int temp = nums[current];
nums[current] = pre;
pre = temp;
count++;
}while(current!=i);
}
}
}
解法四
這個解法是三次反轉,主要也利用瞭解法一中提到的特點——(把數組的變化看成兩部分,左邊的部分右移,右邊的部分左移)
算法思路如下圖:
時間複雜度O(n),空間複雜度O(1)
代碼如下:
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null||nums.length<2||(k=k%nums.length)==0){
return;
}
reverse(nums,0,nums.length-1);
reverse(nums,0,k-1);
reverse(nums,k,nums.length-1);
}
private void reverse(int[] nums,int start,int end){
while(start<end){
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}