[LeetCode] 113. Path Sum II 二叉樹路徑之和之二


 

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

For example:
Given the below binary tree and sum = 22,

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

return

[
   [5,4,11,2],
   [5,8,4,5]
]

這道二叉樹路徑之和在之前那道題 Path Sum 的基礎上又需要找出路徑,但是基本思想都一樣,還是需要用深度優先搜索 DFS,只不過數據結構相對復雜一點,需要用到二維的 vector,而且每當 DFS 搜索到新結點時,都要保存該結點。而且每當找出一條路徑之后,都將這個保存為一維 vector 的路徑保存到最終結果二維 vector 中。並且,每當 DFS 搜索到子結點,發現不是路徑和時,返回上一個結點時,需要把該結點從一維 vector 中移除,參見代碼如下:

 

解法一:

class Solution {
public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        vector<vector<int>> res;
        vector<int> out;
        helper(root, sum, out, res);
        return res;
    }
    void helper(TreeNode* node, int sum, vector<int>& out, vector<vector<int>>& res) {
        if (!node) return;
        out.push_back(node->val);
        if (sum == node->val && !node->left && !node->right) {
            res.push_back(out);
        }
        helper(node->left, sum - node->val, out, res);
        helper(node->right, sum - node->val, out, res);
        out.pop_back();
    }
};

 

下面這種方法是迭代的寫法,用的是中序遍歷的順序,參考之前那道 Binary Tree Inorder Traversal,中序遍歷本來是要用棧來輔助運算的,由於要取出路徑上的結點值,所以用一個 vector 來代替 stack,首先利用 while 循環找到最左子結點,在找的過程中,把路徑中的結點值都加起來,這時候取出 vector 中的尾元素,如果其左右子結點都不存在且當前累加值正好等於 sum 了,將這條路徑取出來存入結果 res 中,下面的部分是和一般的迭代中序寫法有所不同的地方,由於中序遍歷的特點,遍歷到當前結點的時候,是有兩種情況的,有可能此時是從左子結點跳回來的,此時正要去右子結點,則當前的結點值還是算在路徑中的;也有可能當前是從右子結點跳回來的,並且此時要跳回上一個結點去,此時就要減去當前結點值,因為其已經不屬於路徑中的結點了。為了區分這兩種情況,這里使用一個額外指針 pre 來指向前一個結點,如果右子結點存在且不等於 pre,直接將指針移到右子結點,反之更新 pre 為 cur,cur 重置為空,val 減去當前結點,st 刪掉最后一個結點,參見代碼如下:

 

解法二:

class Solution {
public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        vector<vector<int>> res;
        vector<TreeNode*> st;
        TreeNode *cur = root, *pre = nullptr;
        int val = 0;
        while (cur || !st.empty()) {
            while (cur) {
                st.push_back(cur);
                val += cur->val;
                cur = cur->left;
            }
            cur = st.back(); 
            if (!cur->left && !cur->right && val == sum) {
                vector<int> v;
                for (auto &a : st) v.push_back(a->val);
                res.push_back(v);
            }
            if (cur->right && cur->right != pre) {
                cur = cur->right;
            } else {
                pre = cur;
                val -= cur->val;
                st.pop_back();
                cur = nullptr;
            }
        }
        return res;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/113

 

類似題目:

Path Sum

Path Sum IV 

Path Sum III  

Binary Tree Maximum Path Sum

Sum Root to Leaf Numbers

Binary Tree Preorder Traversal

Binary Tree Paths

 

參考資料:

https://leetcode.com/problems/path-sum-ii/

https://leetcode.com/problems/path-sum-ii/discuss/36685/12ms-11-lines-C%2B%2B-Solution

https://leetcode.com/problems/path-sum-ii/discuss/36695/Java-Solution%3A-iterative-and-recursive

https://leetcode.com/problems/path-sum-ii/discuss/36683/DFS-with-one-LinkedList-accepted-java-solution

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM