1. 程式人生 > 其它 >【LeetCode】第112題——路徑總和(難度:簡單)

【LeetCode】第112題——路徑總和(難度:簡單)

技術標籤:二叉樹leetcode遞迴演算法bfsjava

【LeetCode】第112題——路徑總和(難度:簡單)

題目描述

給定一個二叉樹和一個目標和,判斷該樹中是否存在根節點到葉子節點的路徑,這條路徑上所有節點值相加等於目標和。

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

  1. 示例:
    給定如下二叉樹,以及目標和 sum = 22,
    在這裡插入圖片描述
    返回 true, 因為存在目標和為 22 的根節點到葉子節點的路徑 5->4->11->2。

來源:力扣(LeetCode)

連結:https://leetcode-cn.com/problems/path-sum
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

解題思路

思路一:本人認為此題從BFS的解法開始思考比較簡單,如果當前節點的左節點不為空,則把當前節點的加到左節點的上,右節點同理。如果當前節點的等於題目的給定值,且無葉子節點,即可認為滿足題意,返回true。

思路二:遞迴。程式碼相對於思路一來說非常簡練,但是比較難以想到。假定從根節點到當前節點的值之和為val,我們可以將這個大問題轉化為一個小問題:是否存在從當前節點的子節點到葉子的路徑,滿足其路徑和為sum - val。(相當巧妙)

如果一下子用遞迴想不到,就考慮試試用用BFS迴圈解法。

程式碼詳解

思路一:BFS(本人寫的看起來很冗長,但思路很清晰)

/**
 * 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) { // 特殊情況1:空樹,直接返回false if (root == null) { return false; // 特殊情況2:只有根節點,且根節點的值等於給定值(不等於的情況會被後續的程式碼判斷出) } else if (root.val == sum && root.left == null && root.right == null) { return true; } Queue<TreeNode> queue = new LinkedList<>(); // 利用佇列先入先出的特點,BFS慣用思路 TreeNode p = root.left; TreeNode q = root.right; // 如果葉子節點存在,則把根節點的值加到葉子節點的值上 if (p != null) { p.val = p.val + root.val; } if (q != null) { q.val = q.val + root.val; } // 入隊 queue.offer(p); queue.offer(q); while(!queue.isEmpty()){ int size = queue.size(); while(size > 0) { // 出隊 p = queue.poll(); q = queue.poll(); if (p != null) { queue.offer(p.left); queue.offer(p.right); // 三個條件同時滿足才能返回true if (p.val == sum && p.left == null && p.right == null) { return true; } // 否則就把當前節點的val加到葉子節點的value裡 if (p.left != null) { p.left.val = p.left.val + p.val; } if (p.right != null) { p.right.val = p.right.val + p.val; } } // 同左葉子節點 if (q != null) { queue.offer(q.left); queue.offer(q.right); if (q.val == sum && q.left == null && q.right == null) { return true; } if (q.left != null) { q.left.val = q.left.val + q.val; } if (q.right != null) { q.right.val = q.right.val + q.val; } } size = size - 2; } } // 遍歷完了都沒有滿足條件的路徑,返回false return false; } }

思路二:遞迴(此處引用官方題解,我太菜了

class Solution {
    public boolean hasPathSum(TreeNode root, int sum) {
    	// 空樹,返回false
        if (root == null) {
            return false;
        }
        // 遍歷到葉子節點了,判斷當前路徑之和是否等於給定值
        if (root.left == null && root.right == null) {
            return sum == root.val;
        }
        // sum - root.val是神來之筆,佩服
        return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
    }
}

注意點

  1. 本人的BFS思路採用逐層以的方式更新val,判斷是否等於給定值。
  2. 遞迴思路是採用逐層以的方式更新val,判斷最後的值是否等於葉子節點的值。