難度:簡單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--;
}
}
}
複製代碼