LeetCode189:旋轉數組

題目描述

給定一個數組,將數組中的元素向右移動 k 個位置,其中 k 是非負數。

示例

示例 1:

輸入: [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:

輸入: [-1,-100,3,99] 和 k = 2
輸出: [3,99,-1,-100]
解釋:
向右旋轉 1 步: [99,-1,-100,3]
向右旋轉 2 步: [3,99,-1,-100]

答案

解法一:

如果不要求空間複雜度爲O(1)的話,可以利用一個輔助數組(把數組的變化看成兩部分,左邊的部分右移,右邊的部分左移

時間複雜度O(n),空間複雜度O(n)

代碼如下:

class Solution {
    public void rotate(int[] nums, int k) {
        if(nums==null||nums.length<2||(k=k%nums.length)==0){
            return;
        }
        //left存需要往右移的左半部分數組
        int[] left = Arrays.copyOfRange(nums,0,nums.length-k);
        for(int i=0;i<k;i++){
            nums[i] = nums[i+nums.length-k];
        }
        for(int i=k;i<nums.length;i++){
            nums[i] = left[i-k];
        }
        return;
    }
}

解法二

將數組旋轉k次,每次旋轉1個位置

時間複雜度O(n*k),空間複雜度O(1)

代碼如下:

class Solution {
    public void rotate(int[] nums, int k) {
        if(nums==null||nums.length<2||(k=k%nums.length)==0){
            return;
        }
        while(k>0){
            rotateForOne(nums);
            k--;
        }
        
    }
    private void rotateForOne(int[] nums){
        int pre = nums[0];
        for(int i=1;i<nums.length;i++){
            int temp = nums[i];
            nums[i] = pre;
            pre = temp;
        }
        nums[0] = pre;
    }
}

解法三

直接把元素放到它最後應該在的位置(我們需要把被替換的數字保存在變量 temp 裏面。然後,我們將被替換數字temp放到它正確的位置,並繼續這個過程 n次)。這有個問題就是可能在沒有遍歷所有數字的情況下回到出發數字,這就需要加一個判斷,如果出現這個情況,就從下一個數字開始,重複上述過程,直到數組中的所有元素都被移動。

時間複雜度O(n),空間複雜度O(1)

代碼如下:

class Solution {
    public void rotate(int[] nums, int k) {
        if(nums==null||nums.length<2||(k=k%nums.length)==0){
            return;
        }
        int count = 0;//移動的次數,當count==nums.length時,移動結束
        for(int i=0;count<nums.length;i++){
            int current = i;
            int pre = nums[i];
            do{
                current = (current+k)%nums.length;
                int temp = nums[current];
                nums[current] = pre;
                pre = temp;
                count++;
            }while(current!=i);
        }
    }
}

解法四

這個解法是三次反轉,主要也利用瞭解法一中提到的特點——(把數組的變化看成兩部分,左邊的部分右移,右邊的部分左移
在這裏插入圖片描述
算法思路如下圖:
在這裏插入圖片描述

時間複雜度O(n),空間複雜度O(1)

代碼如下:

class Solution {
    public void rotate(int[] nums, int k) {
        if(nums==null||nums.length<2||(k=k%nums.length)==0){
            return;
        }
        reverse(nums,0,nums.length-1);
        reverse(nums,0,k-1);
        reverse(nums,k,nums.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;
            start++;
            end--;
        }
    }

}

圖片來自這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章