LeetCode每日一題: 旋轉數組(No.189)

題目: 旋轉數組


給定一個數組,將數組中的元素向右移動 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;
        }
    }
}複製代碼
相關文章
相關標籤/搜索