題目: 旋轉陣列
給定一個陣列,將陣列中的元素向右移動 k 個位置,其中 k 是非負數。
複製程式碼
示例:
輸入: [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]
輸入: [-1,-100,3,99] 和 k = 2
輸出: [3,99,-1,-100]
解釋:
向右旋轉 1 步: [99,-1,-100,3]
向右旋轉 2 步: [3,99,-1,-100]
複製程式碼
思考:
這道題有一種巧妙地利用反轉的做法。
首先將第0個到第k個元素反轉,再將第k+1到末尾元素反轉,最後再將全部元素反轉即可。
例如:[1,2,3,4,5,6,7] k = 3
將0到3反轉:[4,3,2,1,5,6,7]
將4到6反轉:[4,3,2,1,7,6,5]
全部翻轉:[5,6,7,1,2,3,4] 得到最後結果。
這裡要注意下還有這樣的情況:[1,2] k = 5 即k大於陣列長度的情況。
這裡可以發現陣列旋轉次數等於陣列長度時,旋轉後的陣列與初始陣列相同,轉了一圈又回來了。
1次旋轉:[2,1]
2次旋轉: [1,2] 轉回來了
3次旋轉:[2,1]
4次旋轉: [1,2] 轉回來了
5次旋轉:[2,1]
所以這裡的有效k等於k對陣列長度求餘。
複製程式碼
實現:
class Solution {
public void rotate(int[] nums, int k) {
int length = nums.length;
k %= length;
reverse(nums, 0, length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, 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;
}
}
}複製程式碼