112. Path Sum
EasyDescription
給定一棵二元樹和一個目標值
targetSum,判斷是否存在一條從根到葉子節點的路徑,使得路徑上所有節點值的總和等於targetSum。
Example:
Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 Output: true (路徑 5 -> 4 -> 11 -> 2 = 22)
Intuition#
從根往下走,每經過一個節點就將目標值減去該節點值,到達葉子時檢查是否剛好為零。
- 遞迴傳遞「剩餘目標值」,每層減去當前節點值
- 注意必須走到葉子節點(左右子節點都為 null)才能判斷
Approaches#
⭐ 1: Recursive DFS#
- 概念: 遞迴地將 targetSum 減去當前節點值,到葉子節點時檢查是否為 0
- 時間複雜度:
O(n),最差情況需要遍歷所有節點 - 空間複雜度:
O(h),遞迴堆疊深度
class Solution {
fun hasPathSum(root: TreeNode?, targetSum: Int): Boolean {
if (root == null) return false
val remaining = targetSum - root.`val`
if (root.left == null && root.right == null) {
return remaining == 0
}
return hasPathSum(root.left, remaining) || hasPathSum(root.right, remaining)
}
}2: Iterative DFS with Stack#
- 概念: 用 Stack 存放節點與剩餘目標值的配對,模擬遞迴過程
- 時間複雜度:
O(n) - 空間複雜度:
O(h)
class Solution {
fun hasPathSum(root: TreeNode?, targetSum: Int): Boolean {
if (root == null) return false
val stack = ArrayDeque<Pair<TreeNode, Int>>()
stack.addLast(root to targetSum)
while (stack.isNotEmpty()) {
val (node, remaining) = stack.removeLast()
val newRemaining = remaining - node.`val`
if (node.left == null && node.right == null && newRemaining == 0) {
return true
}
node.left?.let { stack.addLast(it to newRemaining) }
node.right?.let { stack.addLast(it to newRemaining) }
}
return false
}
}🔑 Takeaways#
- Pattern: 路徑和問題 — 遞迴傳遞剩餘值,到葉子節點時做判斷
- 關鍵技巧: 「葉子節點」的判斷是左右子節點都為 null,不要忘記這個條件