題目會給定我們一個陣列和參數k,要求我們將陣列右旋k次,然後輸出內容。
例如[1,2,3,4,5] 右旋 2次,輸出就是[4,5,1,2,3]
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]
Example 2:
Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation:
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]
Constraints:
1 <= nums.length <= 10
5
-2
31
<= nums[i] <= 2
31
- 1
0 <= k <= 10
5
Follow up:
O(1)
extra space?除了第一直覺的創造新array再搬移的方法之外;其實,還有另一個透過三次翻轉來in-place實現(不需要額外創造新array)的方法。
原本的輸入,在右旋k次之後,會有下方的結果
因此,我們可以透過三次反轉(Reverse)來得到等價於右旋k次的效果。
class Solution:
def reverse(self, nums: List[int], start, end):
# reverse array elements within [start, end] interval
while start < end:
nums[start], nums[end] = nums[end], nums[start]
start += 1
end -= 1
def rotate(self, nums: List[int], k: int) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
size = len(nums)
if k > size:
# eliminate redundant rotation which is over size
k = k % size
# reverse all elements
self.reverse( nums, 0, size-1)
# reverse first k elements
self.reverse( nums, 0, k-1)
# reverse last (size - k) elements
self.reverse( nums, k, size-1)
return
時間複雜度:
O( n ) 每次反轉,最多耗費的成本是O(n) ,總共三次反轉=O(3n) = O(n)。
空間複雜度:
O( 1 ) 都是固定尺寸的臨時變數,function call stack也固定只有一層。
矩陣右移這個操作有點像在程式語言中的 >> bitwise右移運算,或者組合語言中的Right shift,觀念上相通的。
實作部分,透過畫圖,可以聯想到用reverse反轉來時做in-place實現,不需要去額外創造新的array去複製搬移。
Reference:
[1] Python/JS/Go/C++ O(n) by reverse [ With comment ] - Rotate Array - LeetCode