天天看點

112. 路徑總和112. 路徑總和

112. 路徑總和

題目連結:112. 路徑總和(簡單)

給你二叉樹的根節點

root

和一個表示目标和的整數

targetSum

。判斷該樹中是否存在 根節點到葉子節點 的路徑,這條路徑上所有節點值相加等于目标和

targetSum

。如果存在,傳回

true

;否則,傳回

false

葉子節點 是指沒有子節點的節點。

示例 1:

輸入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
輸出:true
解釋:等于目标和的根節點到葉節點路徑如上圖所示。      

示例 2:

輸入:root = [1,2,3], targetSum = 5
輸出:false
解釋:樹中存在兩條根節點到葉子節點的路徑:
(1 --> 2): 和為 3
(1 --> 3): 和為 4
不存在 sum = 5 的根節點到葉子節點的路徑。      

示例 3:

輸入:root = [], targetSum = 0
輸出:false
解釋:由于樹是空的,是以不存在根節點到葉子節點的路徑。      

解題思路

該題與257. 二叉樹的所有路徑 很相似,隻是在該題中,如果找到對應的路徑需立即傳回。是以在遞歸方法中,遞歸函數的傳回值不能為 void。

遞歸法

代碼(C++)

//遞歸
class Solution {
public:
     bool traversal(TreeNode* node, int targetSum, int& midSum) {
        if (node->left == nullptr && node->right == nullptr) { // 葉子節點
            if (midSum == targetSum) return true;
            else return false;
        }
        //非葉子節點
        bool result1 = false;
        bool result2 = false;
        if (node->left) {
            midSum += node->left->val;
            result1 = traversal(node->left, targetSum, midSum);
            midSum -= node->left->val; //回溯
        }
        if (node->right) {
            midSum += node->right->val;
            result2 = traversal(node->right, targetSum, midSum);
            midSum -= node->right->val; //回溯
        }
        return result1 || result2;
    }
​
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return false;
        int midSum = root->val;
        bool result = traversal(root, targetSum, midSum);
        return result;
    }
};      

代碼(JavaScript)

// 遞歸法
// 用 count 計數 
function traversal(node, count) {
    if (!node.left && !node.right) {
        if (count === 0) return true;
        else return false;
    }
​
    if (node.left) {
        count -= node.left.val;
        if (traversal(node.left, count)) return true;
        count += node.left.val; //回溯
    }
    if (node.right) {
        count -= node.right.val;
        if (traversal(node.right, count)) return true;
        count += node.right.val; //回溯
    }
    return false;
}
​
var hasPathSum = function(root, targetSum) {
    if (root === null) return false;
    return traversal(root, targetSum - root.val);
};      

疊代法

代碼(C++)

//疊代(前序周遊)
class Solution1 {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        stack<TreeNode*> staNode; //用于處理節點
        stack<int> staSum; //用于處理路徑和
        if (root != nullptr) {
            staNode.push(root);
            staSum.push(root->val);
        }
        while (!staNode.empty()) {
            TreeNode* node = staNode.top();
            staNode.pop();
            int midSum = staSum.top();
            staSum.pop();
            if (node->left == nullptr && node->right == nullptr && midSum == targetSum) return true;
            if (node->right) {
                staNode.push(node->right);
                staSum.push(midSum + node->right->val);
            }
            if (node->left) {
                staNode.push(node->left);
                staSum.push(midSum + node->left->val);
            }
        }
        return false;
    }
};      

代碼(JavaScript)

//疊代
var hasPathSum = function(root, targetSum) {
    let staNode_Sum = [];
    if (root != null) {
        staNode_Sum.push(root.val); // 值先進
        staNode_Sum.push(root); //節點後進
    }
    while (staNode_Sum.length != 0) {
        let node = staNode_Sum.pop(); //節點先出
        let sum = staNode_Sum.pop(); //值後出
        if (node.left === null && node.right === null && sum === targetSum) return true;
        if (node.right) { //右
            staNode_Sum.push(sum + node.right.val); //值先進
            staNode_Sum.push(node.right); //節點後進
        }
        if (node.left) { //左
            staNode_Sum.push(sum + node.left.val); //值先進
            staNode_Sum.push(node.left); //節點後進
        }
    }
    return false;
};