題目: 旋轉數組
給定一個數組,將數組中的元素向右移動 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;
}
}
}複製代碼