LeetCode刷題的Golang小技巧|探索Tree解法

更新於 發佈於 閱讀時間約 8 分鐘

******

這個系列是紀錄個人Leetcode刷題的心得,因為Leetcode題目背後都有要考的核心演算法,若是刷題前能夠熟悉演算法,對於解題會很有幫助!

******


在 Leetcode 的解題過程中,Binary Tree 是一個常見的數據結構,透過不同的遍歷方式可以解決各式各樣的問題。


針對Tree的題目,可以簡單總結三種狀況:

(1) 由上往下探索:使用「深度優先搜尋(DFS)」。

(2) 由左而右逐層探索:使用「廣度優先搜尋(BFS)」。

(3) 由小而大探索:使用「中序遍歷(Inorder Traversal)」。


1. 深度優先搜尋(DFS)- 使用遞迴


※ 觀念:深度優先搜索(DFS)是一種圖或樹的遍歷算法,它從根節點開始,沿著每一條分支深入到盡可能遠的節點,然後回溯並繼續探索其他分支。DFS 使用遞迴或堆疊(Stack)來實現這種深度遍歷。


※ 範例題目:Leetcode 129. Sum Root to Leaf Numbers

  • 問題描述: 給定一棵二元樹,每條從 Root 到 Leaf 的路徑代表一個數字,請計算所有路徑數字的總和。
  • 解法: 使用 DFS 遞迴遍歷樹的左子樹和右子樹,並在過程中累加節點數值。
  1. 每次進入新的節點時,累積當前的數值。
  2. 若遇到 Leaf 節點,將該數值加總。
  3. 若節點為空則回傳 0。
/**ㄟ
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/

func sumNumbers(root *TreeNode) int {
return dfs(root, 0)
}

func dfs (node *TreeNode, input int) int {
if node == nil {
return 0
}

currentSum := 10 * input + node.Val
if node.Left == nil && node.Right == nil {
return currentSum
}

return dfs(node.Left, currentSum) + dfs(node.Right, currentSum)
}


2. 廣度優先搜尋(BFS)- 使用 Queue


※ 觀念:廣度優先搜索(BFS)是一種圖或樹的遍歷算法,它從根節點開始,首先訪問所有相鄰的節點,然後再訪問這些相鄰節點的相鄰節點,依此類推。BFS 使用隊列(Queue)來實現這種層次遍歷。


※ 範例題目:Leetcode 513. Find Bottom Left Tree Value

  • 問題描述: 找出二元樹中最底層、最左側的節點值。
  • 解法: 使用 BFS 層級遍歷樹,每層從左到右訪問所有節點,最後一層的最左側節點即為答案。
  1. 使用 queue 來存放當前層的節點。
  2. 每次取出節點時,先放入右節點再放入左節點,確保最後取出的節點是最底層最左側的節點。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/

func findBottomLeftValue(root *TreeNode) int {
if root == nil {
return 0
}

queue := []*TreeNode{root}
result := 0
for len(queue) > 0 {
leng := len(queue)
result = queue[0].Val
for i := 0; i < leng; i++ {
node := queue[0]
queue = queue[1:]
if node.Left != nil {
queue = append(queue, node.Left)
}

if node.Right != nil {
queue = append(queue, node.Right)
}
}
}

return result
}

3. 中序遍歷(Inorder Traversal)


※ 觀念:inorder 是一種遍歷二元樹的方法,稱為中序遍歷(Inorder Traversal)。在中序遍歷中,節點的訪問順序是:先訪問左子樹,再訪問根節點,最後訪問右子樹。這種遍歷方式特別適用於二元搜索樹(BST),因為它會按升序訪問節點。


※ 範例題目:Leetcode 230. Kth Smallest Element in a BST

  • 問題描述: 找出二元搜尋樹(BST)中第 K 小的元素。
  • 解法: 中序遍歷 BST 會按照遞增順序拜訪節點,因此可以用 inorder 方式遍歷,當訪問到第 K 個節點時即為答案。
  1. 使用遞迴或 stack 進行 inorder 遍歷。
  2. 記錄當前已訪問的節點數量。
  3. 當訪問到第 K 個節點時,直接回傳該節點的值。
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/

func kthSmallest(root *TreeNode, k int) int {
count := 0
result := 0
inorder(root, k, &count, &result)
return result
}

func inorder(node *TreeNode, k int, count *int, result *int) {
if node == nil {
return
}

inorder(node.Left, k, count, result)
*count++
if k == *count {
*result = node.Val
return
}

inorder(node.Right, k, count, result)
}

總結

Binary Tree 的遍歷方式主要包括 DFS(深度優先)、BFS(廣度優先)以及 Inorder(中序遍歷)。不同的問題可以透過不同的遍歷方法來有效解決,例如:

  • DFS 遞迴 適用於由上往下的拜訪、累積計算(如 Sum Root to Leaf Numbers)。
  • BFS 層級遍歷 適用於由左而右的拜訪、按層尋找節點(如 Find Bottom Left Tree Value)。
  • Inorder 遍歷 特別適用於 BST 中的排序問題(如 Kth Smallest Element in a BST)。

透過熟悉這些遍歷方法,可以更靈活地應對各種 Binary Tree 的問題,提升解題能力。

留言
avatar-img
留言分享你的想法!
avatar-img
EMO先生的沙龍
158會員
65內容數
本專題主要放一些投資理財方面的個人研究,投資理念偏向價值投資,習慣從產業的角度、產品營收佔比分析公司體質,近期研究的主題著重於: (1)半導體產業鏈:IC設計、IC製造、CoWos (2)重電產業鏈:台電強韌電網、智慧電網計畫 (3)營建股追蹤:隆大、新美齊、憶聲、順達、名軒
EMO先生的沙龍的其他內容
2025/04/13
大型語言模型的發展,讓人們思考陪伴型機器人是否能成真,文章探討兩種實現方式:主流的語音轉文字LLM方法和新興的Spoken LLMs方法。作者認為Spoken LLMs的發展,能讓AI更自然地與人互動,實現如哆啦A夢般的陪伴型機器人,並進一步提升AI的陪伴功能。
Thumbnail
2025/04/13
大型語言模型的發展,讓人們思考陪伴型機器人是否能成真,文章探討兩種實現方式:主流的語音轉文字LLM方法和新興的Spoken LLMs方法。作者認為Spoken LLMs的發展,能讓AI更自然地與人互動,實現如哆啦A夢般的陪伴型機器人,並進一步提升AI的陪伴功能。
Thumbnail
2025/04/03
頻繁查詢資料庫造成效能瓶頸?本文探討讀寫分離架構,透過主從資料庫分擔讀寫負載,提升系統效能。並深入分析資料一致性、應用層路由、負載均衡及Redis快取等重要面向,提供解決方案及注意事項。
Thumbnail
2025/04/03
頻繁查詢資料庫造成效能瓶頸?本文探討讀寫分離架構,透過主從資料庫分擔讀寫負載,提升系統效能。並深入分析資料一致性、應用層路由、負載均衡及Redis快取等重要面向,提供解決方案及注意事項。
Thumbnail
2025/01/27
本文介紹使用 Golang 解決 LeetCode 題目的技巧,包含運用 map[int]int、slice 實作堆疊、copy 函數高效複製切片、for 迴圈取代 while 迴圈,以及處理鏈結串列的技巧,以提升程式碼效率和可讀性。
Thumbnail
2025/01/27
本文介紹使用 Golang 解決 LeetCode 題目的技巧,包含運用 map[int]int、slice 實作堆疊、copy 函數高效複製切片、for 迴圈取代 while 迴圈,以及處理鏈結串列的技巧,以提升程式碼效率和可讀性。
Thumbnail
看更多
你可能也想看
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
此文章介紹LeetCode中Binary Tree的三種主要遍歷方法:深度優先搜尋(DFS)、廣度優先搜尋(BFS)和中序遍歷(Inorder Traversal),並搭配LeetCode範例題目說明其應用與解題技巧。文末總結各種方法的適用情境,幫助讀者提升解題能力。
Thumbnail
此文章介紹LeetCode中Binary Tree的三種主要遍歷方法:深度優先搜尋(DFS)、廣度優先搜尋(BFS)和中序遍歷(Inorder Traversal),並搭配LeetCode範例題目說明其應用與解題技巧。文末總結各種方法的適用情境,幫助讀者提升解題能力。
Thumbnail
題目敘述 題目會給定我們一顆二元搜索樹的根結點root,和任意兩個樹中的節點p和q。 要求我們找出p, q最靠近的公共祖先節點。 題目的原文敘述 測試範例 Example 1: Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q
Thumbnail
題目敘述 題目會給定我們一顆二元搜索樹的根結點root,和任意兩個樹中的節點p和q。 要求我們找出p, q最靠近的公共祖先節點。 題目的原文敘述 測試範例 Example 1: Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q
Thumbnail
題目會給一顆二元樹,要求我們計算節點值 和 子樹平均值相等的node有幾個。
Thumbnail
題目會給一顆二元樹,要求我們計算節點值 和 子樹平均值相等的node有幾個。
Thumbnail
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
Thumbnail
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
Thumbnail
題目會給定給我們一顆二元樹的根結點, 要求我們輸出上下顛倒的Level-order traversal的拜訪結果。
Thumbnail
題目會給定給我們一顆二元樹的根結點, 要求我們輸出上下顛倒的Level-order traversal的拜訪結果。
Thumbnail
題目會給定給我們一顆二元樹的根結點,要求我們輸出Level-order traversal的拜訪結果。 在這題,我們會複習並利用BFS模板,來實現逐層搜索演算法。
Thumbnail
題目會給定給我們一顆二元樹的根結點,要求我們輸出Level-order traversal的拜訪結果。 在這題,我們會複習並利用BFS模板,來實現逐層搜索演算法。
Thumbnail
其實常見的tree traversal (前序、中序、後序拜訪), 背後的核心觀念都是相同的。 Tree traversal其實就是探索整顆樹的搜索空間,也可以說是探索整顆樹, 只是指定順序略有不同而已。 本文將結合經典的DFS模板,做一個全面性的回顧。
Thumbnail
其實常見的tree traversal (前序、中序、後序拜訪), 背後的核心觀念都是相同的。 Tree traversal其實就是探索整顆樹的搜索空間,也可以說是探索整顆樹, 只是指定順序略有不同而已。 本文將結合經典的DFS模板,做一個全面性的回顧。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News