二元樹的拜訪 結合 DFS深度優先模板

閱讀時間約 7 分鐘
raw-image

其實常見的tree traversal(前序、中序、後序拜訪),

背後的核心觀念都是相同的。

Tree traversal其實就是探索整顆樹的搜索空間,也可以說是探索整顆樹

只是指定順序略有不同而已。

再次回顧,經典的DFS模板

def dfs( parameter ):
 
 if stop condition:
  # update final result if needed
  return result
 
 # general cases:
 dfs( updated parameter )
 return result



宏觀的結構

應用到樹的搜索,preorder/ inorder/ postorder traversal 就變成

請留意註解中,有特別標出preorder / inorder / postorder 所在的順序

def dfs( parameter ):

if stop condition:
# update final result if needed
return []

# general cases:


# preorder: add current node to path

dfs( left sub tree )

# inorder: add current node to path

dfs( right sub tree )

# postorder: add current node to path

return path

其實三者背後的架構是共通的,只有次序稍微調整一下而已


具象化成preorder traversal,就變成了這個樣子

Preorder traversal 的拜訪順序與抽象模型

Preorder traversal 的拜訪順序與抽象模型

class Solution:
 def preorderTraversal(self, root: TreeNode) -> List[int]:
  
  traversal_path = []
  
  def preorder( node ):
   
   if node:
   
    # DFS with preorder:
    # current, current.left, current.right
    traversal_path.append( node.val )
    preorder( node.left )
    preorder( node.right )
  
  # -----------------------------------
  preorder(root)
  return traversal_path

如果再用functional programming 的方式改寫,就變成

class Solution:
 def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
  
  preOrder = lambda node: ( [node.val] + preOrder(node.left) + preOrder(node.right) ) if node else []
  
  return preOrder(root)


再具象化成inorder traversal,就變成了這個樣子

raw-image


class Solution:
 def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
  
  traversal_path = []
  
  def inorder( node ):
   
   if node:
   
    # DFS with inorder:
    # current.left, current, current.right
    inorder( node.left )
    traversal_path.append( node.val )
    inorder( node.right )
  
  # -----------------------------------
  inorder(root)
  return traversal_path

如果再用functional programming 的方式改寫,就變成

class Solution:
 def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:

  inOrder = lambda node: ( inOrder(node.left) + [node.val] + inOrder(node.right) ) if node else []

  return inOrder(root)

同樣的手法,

再具象化成postorder traversal,就變成了這個樣子

raw-image


class Solution:
 def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
  
  traversal_path = []
  
  def postorder( node ):
   
   if node:
   
    # DFS with postorder:
    # current.left, current.right, current
    postorder( node.left )
    postorder( node.right )
    traversal_path.append( node.val )
  
  # -----------------------------------
  postorder(root)
  return traversal_path

如果再用functional programming 的方式改寫,就變成

class Solution:
 def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
  
  postOrder = lambda node: ( postOrder(node.left) + postOrder(node.right) + [node.val] ) if node else []

  return postOrder(root)



Reference

[1] https://leetcode.com/problems/binary-tree-preorder-traversal/

[2] https://leetcode.com/problems/binary-tree-inorder-traversal/

[3] https://leetcode.com/problems/binary-tree-postorder-traversal/

86會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
發表第一個留言支持創作者!
題目會給定一顆樹,要求我們輸出所有從Root node根節點 到 Leaf node 葉子節點的路徑。 我們會介紹DFS模板 + Tree search演算法的框架來解題
Leetcode #101 Symmetric Tree 題目會給定一顆樹,要求我們判定這棵樹是不是左右鏡像對稱(Symmetric)。
圖論常用的演算法BFS 與 DFS 的統整與比較。 介紹常用且相關的底層資料結構 並且,介紹幾個適合使用的應用領域、解題分類。
Leetcode #100: Same Tree 題目會給定兩棵Binary Tree的根結點,要求我們判斷兩棵樹是否一模一樣。 也就是說,形狀相同,節點的數值也相同。
進階圖論題目: 計算最短的一筆畫路徑長 題目會給定我們一張圖和對應的相鄰矩陣,要求我們返回一筆畫拜訪所有節點的最短路徑長,起終點不拘。
Coin Change + DP 策略_Leetcode 面試題 上機考 題目 詳細解說
題目會給定一顆樹,要求我們輸出所有從Root node根節點 到 Leaf node 葉子節點的路徑。 我們會介紹DFS模板 + Tree search演算法的框架來解題
Leetcode #101 Symmetric Tree 題目會給定一顆樹,要求我們判定這棵樹是不是左右鏡像對稱(Symmetric)。
圖論常用的演算法BFS 與 DFS 的統整與比較。 介紹常用且相關的底層資料結構 並且,介紹幾個適合使用的應用領域、解題分類。
Leetcode #100: Same Tree 題目會給定兩棵Binary Tree的根結點,要求我們判斷兩棵樹是否一模一樣。 也就是說,形狀相同,節點的數值也相同。
進階圖論題目: 計算最短的一筆畫路徑長 題目會給定我們一張圖和對應的相鄰矩陣,要求我們返回一筆畫拜訪所有節點的最短路徑長,起終點不拘。
Coin Change + DP 策略_Leetcode 面試題 上機考 題目 詳細解說
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
 Binary Tree Inorder Traversal 題目給定一個二元樹的根結點。 請輸出中序拜訪(In-order traversal)的拜訪序列。 中序拜訪的定義: 1.拜訪左子樹。 2.拜訪目前的節點。 3.拜訪右子樹。
Thumbnail
題目敘述 145. Binary Tree Postorder Traversal 題目給定一個二元樹的根結點。 請輸出後序拜訪(Post-order traversal)的拜訪序列。 後序拜訪的定義: 1.拜訪左子樹。 2.拜訪右子樹。 3.拜訪目前的節點。
Thumbnail
題目敘述 題目會給定一個二元樹的樹根結點Root node,要求我們計算這顆二元樹的最大深度是多少? 二元樹的深度的定義: 從根結點到葉子結點的最大路徑長度。 題目的原文敘述 約束條件 Constraints: The number of nodes in the tree is
Thumbnail
題目敘述 題目會給我們一顆二元樹的根結點,請我們列出每一層最右邊的節點值,以陣列的形式返回答案。 題目的原文敘述 測試範例 Example 1: Input: root = [1,2,3,null,5,null,4] Output: [1,3,4] 每一層最右邊的節點值分別是1, 3,
Thumbnail
其實常見的tree traversal (前序、中序、後序拜訪), 背後的核心觀念都是相同的。 Tree traversal其實就是探索整顆樹的搜索空間,也可以說是探索整顆樹, 只是指定順序略有不同而已。 本文將結合經典的DFS模板,做一個全面性的回顧。
身為完美主義的我,近日發現我對自己的要求嚴格外,對於腦袋的思考也不忘清理"惡"想法,連想都不想(不敢想XD)
Thumbnail
光明與黑暗,兩者之間在很多人看來,是對立的。但其實這只是讓靈魂學習所要經歷的狀態,親身體驗後,可以選擇繼續成長下去,或者固步自封,繼續在自己認為安全的世界裡活下去。
Thumbnail
易經有云「易有太極,是生兩儀,兩儀生四象,四象生八卦」,在我們的世界裡,所有物質皆由二元組成,世間萬象,看似多變,事實上卻是離不開陰陽兩極。正所謂「孤陽不生,孤陰不長」說明着兩者只能相互依存而生,所以有陰必有陽,有明便有暗。
Thumbnail
這次要介紹的這本書我想無疑是台灣去年相當有討論熱度的書,統統我的選書習慣一直是不去追求市場趨勢,專心看自己有興趣的書,但當我看到人類大歷史的作者,對這本書也給予高度評價時,讓我也一頭栽進人性最根源的探討。
Thumbnail
當二元一次方程式跟列出所有解,以及應用題都沒太多問題後,就會進入解聯立方程式的範圍。在此要建立的第一個概念,就是兩個未知數就得要兩個方程式去求,才會有唯一解。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
 Binary Tree Inorder Traversal 題目給定一個二元樹的根結點。 請輸出中序拜訪(In-order traversal)的拜訪序列。 中序拜訪的定義: 1.拜訪左子樹。 2.拜訪目前的節點。 3.拜訪右子樹。
Thumbnail
題目敘述 145. Binary Tree Postorder Traversal 題目給定一個二元樹的根結點。 請輸出後序拜訪(Post-order traversal)的拜訪序列。 後序拜訪的定義: 1.拜訪左子樹。 2.拜訪右子樹。 3.拜訪目前的節點。
Thumbnail
題目敘述 題目會給定一個二元樹的樹根結點Root node,要求我們計算這顆二元樹的最大深度是多少? 二元樹的深度的定義: 從根結點到葉子結點的最大路徑長度。 題目的原文敘述 約束條件 Constraints: The number of nodes in the tree is
Thumbnail
題目敘述 題目會給我們一顆二元樹的根結點,請我們列出每一層最右邊的節點值,以陣列的形式返回答案。 題目的原文敘述 測試範例 Example 1: Input: root = [1,2,3,null,5,null,4] Output: [1,3,4] 每一層最右邊的節點值分別是1, 3,
Thumbnail
其實常見的tree traversal (前序、中序、後序拜訪), 背後的核心觀念都是相同的。 Tree traversal其實就是探索整顆樹的搜索空間,也可以說是探索整顆樹, 只是指定順序略有不同而已。 本文將結合經典的DFS模板,做一個全面性的回顧。
身為完美主義的我,近日發現我對自己的要求嚴格外,對於腦袋的思考也不忘清理"惡"想法,連想都不想(不敢想XD)
Thumbnail
光明與黑暗,兩者之間在很多人看來,是對立的。但其實這只是讓靈魂學習所要經歷的狀態,親身體驗後,可以選擇繼續成長下去,或者固步自封,繼續在自己認為安全的世界裡活下去。
Thumbnail
易經有云「易有太極,是生兩儀,兩儀生四象,四象生八卦」,在我們的世界裡,所有物質皆由二元組成,世間萬象,看似多變,事實上卻是離不開陰陽兩極。正所謂「孤陽不生,孤陰不長」說明着兩者只能相互依存而生,所以有陰必有陽,有明便有暗。
Thumbnail
這次要介紹的這本書我想無疑是台灣去年相當有討論熱度的書,統統我的選書習慣一直是不去追求市場趨勢,專心看自己有興趣的書,但當我看到人類大歷史的作者,對這本書也給予高度評價時,讓我也一頭栽進人性最根源的探討。
Thumbnail
當二元一次方程式跟列出所有解,以及應用題都沒太多問題後,就會進入解聯立方程式的範圍。在此要建立的第一個概念,就是兩個未知數就得要兩個方程式去求,才會有唯一解。