【Leetcode刷題】漢諾塔
阿新 • • 發佈:2020-07-31
https://leetcode-cn.com/problems/hanota-lcci/
先將最底層圓盤之上的圓盤看做一個整體。漢諾塔問題的本質是
- 將最底層圓盤之上的圓盤全部放到輔助柱上
- 將最底層圓盤放到目標柱上
- 遞迴地處理輔助柱上的圓盤
而第一步又可以變成一個目標柱為輔助柱的漢諾塔問題,即self.hanota(A[1:], C, B)
但是要注意這樣寫是錯誤的,因為切片操作產生了一個新的物件,導致不會直接修改到A
因此,需要一個索引記錄下A需要處理到哪個位置
class Solution(object): def hanota(self, A, B, C): """ :type A: List[int] :type B: List[int] :type C: List[int] :rtype: None Do not return anything, modify C in-place instead. """ # self.hanota(A[1:], C, B) 是錯誤的 # 需要一個索引記錄下A需要處理到哪個位置 def move(n, a, b, c): # 索引為0表示A中沒需要處理的元素了 if n == 0: return # 1. 將最底層圓盤之上的圓盤全部放到輔助柱B上 move(n-1, a, c, b) # 2. 將最底層圓盤放到目標柱上 c.append(a.pop()) # 3. 將輔助柱B上的圓盤移到目標柱 move(n-1, b, a, c) # 因為索引為0表示A中沒有需要處理的元素 # 因此n初始化為len(A),遍歷完A中所有元素後n剛好是0 move(len(A), A, B, C)
-
時間複雜度:O(2n)。
推導:
由於move函式的意義是將A中元素逐個移到C中,因此運算次數與n有關,設move函式的運算次數為T(n),則需要T(n-1)步將最底層圓盤之上的圓盤全部放到輔助柱B上,一步將最底層圓盤放到目標柱上,還需要T(n-1)步將輔助柱B上的圓盤移到目標柱。
由此可得
T(n) = 2T(n-1) + 1
等式兩邊加一得
T(n) + 1 = 2T(n-1) + 2
因此可得T(n)是一個公比為2的等比數列,即T(n) = 2n
-
空間複雜度:O(n)。遞迴深度是n