亞寵展、全球寵物產業風向標——亞洲寵物展覽會深度解析
1091
2022-05-28
一、題目描述
有 A,B,C 三根柱子,A 上面有 n 個盤子,想把 A 上面的盤子移動到 C 上,但是要滿足以下三個條件:
每次只能移動一個盤子;
盤子只能從柱子頂端滑出移到下一根柱子;
盤子只能疊在比它大的盤子上。
請編寫程序,用棧將所有盤子從第一根柱子移到最后一根柱子。
需要原地修改棧。
示例 1:
輸入:A = [2, 1, 0], B = [], C = [] 輸出:C = [2, 1, 0]
1
2
示例 2:
輸入:A = [1, 0], B = [], C = [] 輸出:C = [1, 0]
1
2
二、解題思路:遞歸與分治
這是一道遞歸方法的經典題目,乍一想還挺難理清頭緒的,我們不妨先從簡單的入手:
假設 n = 1,只有一個盤子,很簡單,直接把它從 A 中拿出來,移到 C 上;
如果 n = 2 呢?這時候就要借助 B 了,因為小盤子必須時刻都在大盤子上面,共需要 4 步。
如果 n > 2 呢?思路和上面是一樣的,把 n 個盤子也看成兩個部分,一部分有 1 個盤子,另一部分有 n - 1 個盤子:
觀察上圖,可能會產生疑問:那么 n - 1 個盤子是怎么從 A 移到 C 的呢?
注意,當你在思考這個問題的時候,就將最初的 n 個盤子從 A 移到 C 的問題,轉化成了將 n - 1 個盤子從 A 移到 C 的問題, 依次類推,直至轉化成 1 個盤子的問題時,問題也就解決,這就是分治的思想。
而實現分治思想的常用方法就是遞歸。不難發現,如果原問題可以分解成若干個與原問題結構相同但規模較小的子問題時,往往可以用遞歸的方法解決。具體解決辦法如下:
n = 1 時,直接把盤子從 A 移到 C;
n > 1 時,先把上面 n - 1 個盤子從 A 移到 B(子問題,遞歸);再將最大的盤子從 A 移到 C;再將 B 上 n - 1 個盤子從 B 移到 C(子問題,遞歸)。
三、算法示例
Python 算法示例:
class Solution: def hanota(self, A: List[int], B: List[int], C: List[int]) -> None: n = len(A) self.move(n, A, B, C) # 定義move 函數移動漢諾塔 def move(self,n, A, B, C): if n == 1: C.append(A[-1]) A.pop() return else: self.move(n-1, A, C, B) # 將A上面n-1個通過C移到B C.append(A[-1]) # 將A最后一個移到C A.pop() # 這時,A空了 self.move(n-1,B, A, C) # 將B上面n-1個通過空的A移到C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Java 算法示例:
class Solution { public void hanota(List
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
四、復雜度分析
時間復雜度:O(2n ?1)。一共需要移動的次數。
空間復雜度:O(1)。
Python 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。