
長さnの配列をk個右に回転させる問題。
There are at least three different ways to solve this problem.と書いてあったので、色々試してみた。
Just a moment...
全探索
1個ずらす作業をk回繰り返す。
時間計算量はO(NxK)かかるが、inplaceで作業できるので空間計算量が0。
ただし、提出しても時間切れ。
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        k %= len(nums)
        
        for i in range(k):
            prev = nums[-1]
            for j in range(len(nums)):
                prev, nums[j] = nums[j], prev
        pop/insert
末尾を先頭に持ってきた後に末尾を削除する。
popメソッドはデフォルトで末尾を削除する。
ただし、insertメソットはO(N)が要求されるため遅い。
TimeComplexity - Python Wiki
O(N)のinsertをK回繰り返すため時間計算量はO(K)。
inplaceで実行出来るので空間計算量はO(1)。
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        for i in range(k):
            nums.insert(0, nums[-1])
            nums.pop()
            外部配列を使う
値を保存するための長さNの配列を別に用意する。
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        k %= len(nums)
        
        temp = nums[-k:] + nums[:-k]
        for i in range(len(nums)):
            nums[i] = temp[i]循環
K個先の値と入れ替え、そのまたK個先の値と入れ替え、・・・を繰り返していく。
スタート地点に帰ってきたら同じループに入ってしまうので、breakしてスタート地点を1つずらし、同じことを繰り返す。
入れ替えた回数countを保存しておき、全部でN個の要素を入れ替えたら終了するため時間計算量はO(N)。
空間計算量は数個の変数を確保するだけなのでO(1)。
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        k %= len(nums)
        n = len(nums)
        
        start_idx = 0
        count = 0
        
        while count < n:
            current_idx, prev_value = start_idx, nums[start_idx]
            while True:
                next_idx = (current_idx + k) % n
                nums[next_idx], prev_value = prev_value, nums[next_idx]
                current_idx = next_idx
                count += 1
                
                if start_idx == current_idx:
                    break
            
            start_idx += 1
        反転
K個回転させるということは、全体を反転させた後、前方K個と残りのN-K個をそれぞれ反転させることに等しい。
O(N)の反転を3返すため、時間計算量は定数倍を取り除いてO(N)。
inplaceで実行可能なので外部メモリは必要なく、空間計算量はO(1)。
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        k %= len(nums)
        n = len(nums)
        
        nums[:] = reversed(nums)
        nums[:k] = reversed(nums[:k])
        nums[k:] = reversed(nums[k:]) 
  
  
  
  
コメント