LeetCode每日一題: 旋轉陣列(No.189)

胖宅老鼠發表於2019-05-22

題目: 旋轉陣列


給定一個陣列,將陣列中的元素向右移動 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;
        }
    }
}複製程式碼

相關文章