leecode 旋轉陣列
阿新 • • 發佈:2018-11-02
描述
給定一個數組,將陣列中的元素向右移動 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) 的原地演算法。
解題思路:
解題思路有很多種,下面講述兩種比較巧妙的解法:
1.使用原地替換的方法,首先使用tmp記錄陣列第一個值,從第一個元素開始,不斷的swap(tmp,nums[i]),其中i是tmp值的目標位置;這裡要注意的一個情況就是移動的步數k是陣列長度的因子,這樣會出現重複迴圈的情況,需要一個標誌位來標識這種情況從而打破迴圈;
void rotate(vector<int>& nums, int k) {if(nums.empty()) { return; } k %= nums.size(); int len = nums.size(); int c = len; int tmp = nums[0]; int i=0; int mark = i; while(c-- >= 0) { i = (i + k) >= len ? i + k - len : i+k; swap(nums[i],tmp);if(c > 0 && i == mark) { ++i; tmp = nums[i]; mark = i; } } }
2.通過觀察目標陣列可以發現,目標陣列的前k位是原陣列的最後n-k位,所以通過反轉陣列實現,首先反轉前n-k個元素,再反轉後k個元素,最後反轉整個陣列實現。
Solution {
void rotate(vector<int>& nums, int k) { if(nums.empty()) { return; } int len = nums.size(); if(k % len == 0) { return; } k %= len; reverse(nums,0,len - k - 1); reverse(nums,len -k,len - 1); reverse(nums,0,len-1); } void reverse(vector<int>& nums,int start,int end) { while(start < end) { swap(nums[start],nums[end]); ++start; --end; } }
};