O1空間複雜度實現陣列迴圈右移_LeetCode189

fashionbrother發表於2020-12-07

問題描述

給定一個陣列,將陣列中的元素向右移動 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]

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/rotate-array


環狀陣列法

  通過取模運算可以確定 n u m s [ i ] nums[i] nums[i]應該移動到的下標為 ( i + k ) % n u m s . s i z e ( ) (i+k)\%nums.size() (i+k)%nums.size(),依次執行右移操作。過程中如果出現環(即回到最初開始移動的下標 i i i),則從 i + 1 i+1 i+1開始繼續右移。整個過程通過計數器 c o u n t count count記錄已經右移的個數, c o u n t = n u m s . s i z e ( ) count=nums.size() count=nums.size()時右移結束。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if(nums.size()==0) return;
        k = k % nums.size();
        //nex當前要右移的數,i nex要右移至的下標
        //start當前環形陣列的起始下標
        //count計數器,已經右移的個數
        int nex = nums[0],start = 0, count = 0, i = (0+k)%nums.size();
        while(count < nums.size()){
            int tmp = nums[i];  //暫存原來的nums[i]
            nums[i] = nex;      //右移賦值
            nex = tmp;          //更新下一輪右移的nex
            count++;            //右移數+1
            if(i==start){       //出現環
                i = (i+1)%nums.size(); //處理下一個數
                nex = nums[i];         //更新新的nex
                start = i;             //更新新的start
            }
            i = (i+k)%nums.size();//更新下一次要右移至的下標
        }
    }
};

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


反轉元素法

  首先將原陣列反轉,然後將前 k k k個元素反轉,最後將後 n − k n-k nk個元素反轉。

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
       if(nums.size()==0) return;
        k = k % nums.size();
        reverse(nums.begin(),nums.end());
        reverse(nums.begin(),nums.begin()+k);
        reverse(nums.begin()+k, nums.end());
    }
};

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


參考

[1] https://leetcode-cn.com/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode/

相關文章