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
155會員
57內容數
本專題主要放一些投資理財方面的個人研究,投資理念偏向價值投資,習慣從產業的角度、產品營收佔比分析公司體質,近期研究的主題著重於: (1)半導體產業鏈:IC設計、IC製造、CoWos (2)重電產業鏈:台電強韌電網、智慧電網計畫 (3)營建股追蹤:隆大、新美齊、憶聲、順達、名軒
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
EMO先生的沙龍 的其他內容
本文介紹使用 Golang 解決 LeetCode 題目的技巧,包含運用 map[int]int、slice 實作堆疊、copy 函數高效複製切片、for 迴圈取代 while 迴圈,以及處理鏈結串列的技巧,以提升程式碼效率和可讀性。
本文介紹使用 Golang 解決 LeetCode 題目的技巧,包含運用 map[int]int、slice 實作堆疊、copy 函數高效複製切片、for 迴圈取代 while 迴圈,以及處理鏈結串列的技巧,以提升程式碼效率和可讀性。
你可能也想看
Google News 追蹤
提問的內容越是清晰,強者、聰明人越能在短時間內做判斷、給出精準的建議,他們會對你產生「好印象」,認定你是「積極」的人,有機會、好人脈會不自覺地想引薦給你
Thumbnail
LeetCode 是一個程式語言版的線上題庫平臺,提供題目描述、程式碼區塊、解題者分享的解法和疑問討論。藉由這篇文章分享我在 LeetCode 上的使用經驗和觀點,包括刷題的重要性、解題心態和練習目標。
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
知道如何從一組給定的英文字母和單字庫中的單字拼出最高分的單字組合。使用DFS + 回溯法 + 剪枝優化的演算法,詳細分析瞭如何展開所有可能的路徑,並且找出符合條件的狀態,協助讀者理解演算法背後的思維和方法。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目已經給定一個Trie前綴樹的類別和相關的函式介面interface, 要求我們把功能實作出來。 Trie() 建構子,初始化一個空的Trie。 void insert(String word) 插入一個新的單字word到Trie裡面。 boolean search(Strin
Thumbnail
題目敘述 題目會給我們一棵BST二元搜索樹的根結點root,還有一個指定的目標值key。 要求我們在樹中刪除帶有這個key值的節點,並且返回更新過後二元搜索樹的樹根root。 題目的原文敘述 測試範例 Example 1: Input: root = [5,3,6,2,4,null,
Thumbnail
題目敘述 題目會給我們一棵二元搜索樹的根結點root,還有一個指定的目標值val。 要求我們找出在樹中對應到目標值val的節點,假如找不到,請回傳null( null在Python就是None)。 題目的原文敘述 測試範例 Example 1: Input: root = [4,2,
Thumbnail
題目會給定一顆二元樹的根結點,要求我們驗證這一顆樹是否為合法的二元搜索樹, 也就是所謂的Binary search tree, aka BST?
提問的內容越是清晰,強者、聰明人越能在短時間內做判斷、給出精準的建議,他們會對你產生「好印象」,認定你是「積極」的人,有機會、好人脈會不自覺地想引薦給你
Thumbnail
LeetCode 是一個程式語言版的線上題庫平臺,提供題目描述、程式碼區塊、解題者分享的解法和疑問討論。藉由這篇文章分享我在 LeetCode 上的使用經驗和觀點,包括刷題的重要性、解題心態和練習目標。
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
知道如何從一組給定的英文字母和單字庫中的單字拼出最高分的單字組合。使用DFS + 回溯法 + 剪枝優化的演算法,詳細分析瞭如何展開所有可能的路徑,並且找出符合條件的狀態,協助讀者理解演算法背後的思維和方法。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目已經給定一個Trie前綴樹的類別和相關的函式介面interface, 要求我們把功能實作出來。 Trie() 建構子,初始化一個空的Trie。 void insert(String word) 插入一個新的單字word到Trie裡面。 boolean search(Strin
Thumbnail
題目敘述 題目會給我們一棵BST二元搜索樹的根結點root,還有一個指定的目標值key。 要求我們在樹中刪除帶有這個key值的節點,並且返回更新過後二元搜索樹的樹根root。 題目的原文敘述 測試範例 Example 1: Input: root = [5,3,6,2,4,null,
Thumbnail
題目敘述 題目會給我們一棵二元搜索樹的根結點root,還有一個指定的目標值val。 要求我們找出在樹中對應到目標值val的節點,假如找不到,請回傳null( null在Python就是None)。 題目的原文敘述 測試範例 Example 1: Input: root = [4,2,
Thumbnail
題目會給定一顆二元樹的根結點,要求我們驗證這一顆樹是否為合法的二元搜索樹, 也就是所謂的Binary search tree, aka BST?