iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
Mobile Development

30天用 Swift 解 LeetCode 問題系列 第 20

Day 20 - 543. Diameter of Binary Tree - 解法與複雜度分析 - LeetCode in Swift

  • 分享至 

  • xImage
  •  

hero

基本資訊

題意

給予一個二元樹的根節點 root ,請求出樹的「直徑」。而這邊的直徑就是代表其中兩個節點有可能的「在長距離」。而這個最長距離也有可能不會穿過 root 節點。

思維

看到要找樹的深度,就是要 go deep 。這時候就可以先試試看 DFS (深度優先搜尋) 和 backtracking 。

Backtracking

而對於 backtracking 的 subroutine ,我們必須定義結束遞迴呼叫的條件。

停止條件

  • 當傳入的 root 為零,就回傳 0 不繼續執行

走訪方式

  • 用遞迴走訪左右節點,取得各自的樹高

因此可以拿左右的樹高做兩件事情

  1. 算出這個節點出發的直徑和目前最大直徑比較,有大於的話則更新最大直徑。
  2. 我們只關心最大的樹高,因此找出最大樹高並回傳。

最大直徑

因為不能確定在樹的哪邊會拿到最大值,因此會在遞迴的過程之外需要有個變數來暫存這個值,並在走訪過程中不斷的檢查和更新她。

程式碼

class Solution {
    func diameterOfBinaryTree(_ root: TreeNode?) -> Int {
        var result = 0
        height(root, &result)
        return result
    }

    /// Backtracking
    @discardableResult
    func height(_ root: TreeNode?,_ result: inout Int) -> Int {
        if root == nil { return 0 }

        let left = height(root?.left, &result)
        let right = height(root?.right, &result)

        result = max(result, left + right)
        return max(left, right) + 1
    }
}

執行結果

  • Runtime: 19 ms (Beats 95.26%)
  • Memory: 14.6 MB (Beats 25.30%)

複雜度分析

令 n 為節點數

Big O 說明
時間複雜度 O(n) 必須走過每個節點才能知道所有的可能性
空間複雜度 O(n) 每一個 subroutine 都會宣告 left 和 right 來暫存,所以實際上是 2n ,不過我們可以把它簡化成 n

結語

以上,就是今天的 LeetCode in Swift ,

如果有什麼問題和回饋歡迎留言一起討論,今天就到這裡,明天見!


上一篇
Day 19 - 1408. String Matching in an Array - 解法與複雜度分析 - LeetCode in Swift
下一篇
Day 21 - 136. Single Number - 解法與複雜度分析 - LeetCode in Swift
系列文
30天用 Swift 解 LeetCode 問題30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言