首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

LeetCode 112. 路徑總和:遞歸與迭代雙解法詳解

     編輯:Java 綜合教學

題目描述

給定一棵二叉樹和一個目標和 sum,判斷樹中是否存在從根節點到葉子節點的路徑,使得路徑上所有節點值的和等於目標和。

說明:葉子節點是指沒有子節點的節點。

示例

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

給定 sum = 22,存在路徑 5 → 4 → 11 → 2,和為 22,返回 true。

解法一:遞歸 DFS(深度優先搜索)

核心思路:將問題轉化為子問題——從當前節點出發,是否存在路徑和為 sum - node.val。遇到葉子節點時直接判斷剩餘值是否等於節點值。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null) {
            return false;
        }
        // 到達葉子節點,判斷剩餘值是否匹配
        if (root.left == null && root.right == null) {
            return sum == root.val;
        }
        // 遞歸檢查左右子樹,目標和遞減
        return hasPathSum(root.left, sum - root.val) 
            || hasPathSum(root.right, sum - root.val);
    }
}

複雜度分析:

  • 時間複雜度:O(N),N 為節點數,每個節點訪問一次
  • 空間複雜度:O(H),H 為樹高,遞歸棧空間;最壞情況(鏈狀樹)為 O(N)

解法二:迭代 BFS(廣度優先搜索)+ 隊列

核心思路:使用隊列同時存儲節點與從根到該節點的路徑和。層序遍歷,遇到葉子節點檢查路徑和是否等於目標值。

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null) return false;
        
        Queue nodeQueue = new LinkedList<>();
        Queue sumQueue = new LinkedList<>();
        nodeQueue.offer(root);
        sumQueue.offer(root.val);
        
        while (!nodeQueue.isEmpty()) {
            TreeNode node = nodeQueue.poll();
            int currentSum = sumQueue.poll();
            
            // 遇到葉子節點,檢查路徑和
            if (node.left == null && node.right == null) {
                if (currentSum == sum) return true;
            }
            
            if (node.left != null) {
                nodeQueue.offer(node.left);
                sumQueue.offer(currentSum + node.left.val);
            }
            if (node.right != null) {
                nodeQueue.offer(node.right);
                sumQueue.offer(currentSum + node.right.val);
            }
        }
        return false;
    }
}

複雜度分析:

  • 時間複雜度:O(N)
  • 空間複雜度:O(N),隊列最多存儲一層節點,滿二叉樹最底層約 N/2 個節點

解法三:迭代 DFS(棧)

同樣可用棧模擬遞歸,適合不想用遞歸且偏好深度優先的場景:

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
        if (root == null) return false;
        
        Deque nodeStack = new ArrayDeque<>();
        Deque sumStack = new ArrayDeque<>();
        nodeStack.push(root);
        sumStack.push(root.val);
        
        while (!nodeStack.isEmpty()) {
            TreeNode node = nodeStack.pop();
            int currentSum = sumStack.pop();
            
            if (node.left == null && node.right == null && currentSum == sum) {
                return true;
            }
            
            if (node.right != null) {
                nodeStack.push(node.right);
                sumStack.push(currentSum + node.right.val);
            }
            if (node.left != null) {
                nodeStack.push(node.left);
                sumStack.push(currentSum + node.left.val);
            }
        }
        return false;
    }
}

總結與避坑指南

  1. 葉子節點判斷:必須是 left == null && right == null,單側有子節點不算葉子
  2. 空樹處理:root == null 直接返回 false
  3. 負數值支持:題目未限制節點值為正,解法需支持負數,上述代碼均無問題
  4. 遞歸 vs 迭代:遞歸代碼簡潔,但深樹可能棧溢出;迭代可控性更強,生產環境推薦

本題是樹形 DP 的入門範例,掌握「路徑和」狀態傳遞模式,對後續解決「路徑總和 II/III」、「最大路徑和」等進階題目極有幫助。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved