1. 程式人生 > 其它 >路徑總和II——深度優先於廣度優先的實踐

路徑總和II——深度優先於廣度優先的實踐

技術標籤:LeetCode

一、題目

給定一個二叉樹和一個目標和,找到所有從根節點到葉子節點路徑總和等於給定目標和的路徑。說明: 葉子節點是指沒有子節點的節點。

示例:給定如下二叉樹,以及目標和 sum = 22,

二、題解

注意到本題的要求是,找到所有滿足從「根節點」到某個「葉子節點」經過的路徑上的節點之和等於目標和的路徑。核心思想是對樹進行一次遍歷,在遍歷時記錄從根節點到當前節點的路徑和,以防止重複計算。

2.1深度優先搜尋

我們可以採用深度優先搜尋的方式,列舉每一條從根節點到葉子節點的路徑。當我們遍歷到葉子節點,且此時路徑和恰為目標和時,我們就找到了一條滿足條件的路徑。

class Solution {
public:
    vector<vector<int>> ret;
    vector<int> path;

    void dfs(TreeNode* root, int sum) {
        if (root == nullptr) {
            return;
        }
        path.emplace_back(root->val);
        sum -= root->val;
        if (root->left == nullptr && root->right == nullptr && sum == 0) {
            ret.emplace_back(path);
        }
        dfs(root->left, sum);
        dfs(root->right, sum);
        path.pop_back();
    }

    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        dfs(root, sum);
        return ret;
    }
};


2.2廣度優先搜尋

我們也可以採用廣度優先搜尋的方式,遍歷這棵樹。當我們遍歷到葉子節點,且此時路徑和恰為目標和時,我們就找到了一條滿足條件的路徑。

為了節省空間,我們使用雜湊表記錄樹中的每一個節點的父節點。每次找到一個滿足條件的節點,我們就從該節點出發不斷向父節點迭代,即可還原出從根節點到當前節點的路徑。

class Solution {
public:
    vector<vector<int>> ret;
    unordered_map<TreeNode*, TreeNode*> parent;

    void getPath(TreeNode* node) {
        vector<int> tmp;
        while (node != nullptr) {
            tmp.emplace_back(node->val);
            node = parent[node];
        }
        reverse(tmp.begin(), tmp.end());
        ret.emplace_back(tmp);
    }

    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        if (root == nullptr) {
            return ret;
        }

        queue<TreeNode*> que_node;
        queue<int> que_sum;
        que_node.emplace(root);
        que_sum.emplace(0);

        while (!que_node.empty()) {
            TreeNode* node = que_node.front();
            que_node.pop();
            int rec = que_sum.front() + node->val;
            que_sum.pop();

            if (node->left == nullptr && node->right == nullptr) {
                if (rec == sum) {
                    getPath(node);
                }
            } else {
                if (node->left != nullptr) {
                    parent[node->left] = node;
                    que_node.emplace(node->left);
                    que_sum.emplace(rec);
                }
                if (node->right != nullptr) {
                    parent[node->right] = node;
                    que_node.emplace(node->right);
                    que_sum.emplace(rec);
                }
            }
        }

        return ret;
    }
};

參考:

https://leetcode-cn.com/problems/path-sum-ii/solution/lu-jing-zong-he-ii-by-leetcode-solution/