難度:簡單java
題庫地址:leetcode-cn.com/problems/ro…算法
給定一個數組,將數組中的元素向右移動 k 個位置,其中 k 是非負數。數組
示例 1:bash
輸入: [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:spa
輸入: [-1,-100,3,99] 和 k = 2
輸出: [3,99,-1,-100]
解釋:
向右旋轉 1 步: [99,-1,-100,3]
向右旋轉 2 步: [3,99,-1,-100]
複製代碼
說明:.net
英文版的有答案:leetcode.com/problems/ro…3d
這裏記錄一下第4種方法的理解:Approach #4 Using Reverse [Accepted]code
假設對長度爲 n 的數組,進行 k 次旋轉。leetcode
首先要找到最終有效的次數,由於旋轉的循環的,當對數組進行 n 次旋轉時,至關於沒有對數組進行操做,同時該方法必須先找到最終有效次數,不然無法對數組進行鏡像操做。get
爲何在不一樣位置採用三次鏡像操做就能實現數組的 k 次旋轉,連同答案和本身的理解整理爲以下:
先計算 的有效次數,由於旋轉是循環進行的,像自行車鏈條同樣,當元素旋轉一整圈即: 時,全部元素回到了原來的位置,因此 次旋轉的有效次數爲 。
咱們將數組以 爲邊界拆分紅兩部分看待,前 個元素部分: 和 後 個元素部分 ,爲何以 爲分界點呢?由於對數組進行 次旋轉後, 和 將互換位置。 如數組:,長度 ,進行 次旋轉,對應 ,,旋轉結束後獲得數組: ,
爲了實現將 和 位置互換,這裏採用將整個數組鏡像的策略。 原元素: 鏡像後:
對數組進行鏡像操做後,雖然 和 位置互換,可是其內部元素也被鏡像了,爲了將 和 內部元素的順序恢復,對 和 再分別進行一次鏡像。
舉例以下原數組: 鏡像前: , 鏡像後: , 對 和 分別進行一次鏡像後獲得的最終結果: , 最終答案:
算法思想再精簡一點以下:
Java實現:
class Solution {
public void rotate(int[] nums, int k) {
if (nums == null || nums.length < 2) {
return;
}
// 計算有效旋轉次數
k %= nums.length;
// 對整個數組鏡像,使 S2 和 S1 位置互換
reverse(nums, 0, nums.length - 1);
// 對 S2 鏡像處理,使其內部元素順序恢復
reverse(nums, 0, k - 1);
// 對 S1 鏡像處理,使其內部元素順序恢復
reverse(nums, k, nums.length - 1);
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[end];
nums[end] = nums[start];
nums[start] = temp;
start++;
end--;
}
}
}
複製代碼