Files
leetcode-master/problems/0113.路径总和II.md
youngyangyang04 dd2d8a0718 Update
2020-10-08 10:33:40 +08:00

3.2 KiB
Raw Blame History

链接

思路

这道题目与其说是递归,不如说是回溯问题,题目要找到所有的路径。

这道题目相对于112. 路径总和 ,是要求出所有的路径和。

相信很多同学都疑惑递归的过程中究竟什么时候需要返回值,什么时候不需要返回值?

我在112. 路径总和题解中给出了详细的解释。

如果需要搜索整颗二叉树,那么递归函数就不要返回值,如果要搜索其中一条符合条件的路径,递归函数就需要返回值,因为遇到符合条件的路径了就要及时返回。

而本题要遍历整个树,找到所有路径,所以本题的递归函数不要返回值!

如图:

这道题目其实比112. 路径总和简单一些,大家做完了本题,可以在做112. 路径总和

为了尽可能的把回溯过程体现出来,我写出如下代码(这个代码一定不是最简洁的,但是比较清晰的,过于简洁的代码不方便读者理解

回溯C++代码

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    // 递归函数不需要返回值,因为我们要遍历整个树
    void traversal(TreeNode* cur, int count) {
        if (!cur->left && !cur->right && count == 0) { // 遇到了叶子节点切找到了和为sum的路径
            result.push_back(path);
            return;
        }

        if (!cur->left && !cur->right) return ; // 遇到叶子节点而没有找到合适的边,直接返回

        if (cur->left) { // 左 (空节点不遍历)
            path.push_back(cur->left->val);
            count -= cur->left->val;
            traversal(cur->left, count);    // 递归
            count += cur->left->val;        // 回溯
            path.pop_back();                // 回溯
        }
        if (cur->right) { // 右 (空节点不遍历)
            path.push_back(cur->right->val);
            count -= cur->right->val;
            traversal(cur->right, count);   // 递归
            count += cur->right->val;       // 回溯
            path.pop_back();                // 回溯
        }
        return ;
    }

public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        result.clear();
        path.clear();
        if (root == NULL) return result;
        path.push_back(root->val); // 把根节点放进路径
        traversal(root, sum - root->val);
        return result;
    }
};

这道题目也可以用迭代法相对于112.路径总和,每个节点不仅要保存当前路径和,也要保存当前路径,其实比较麻烦,也没有必要,因为回溯法虽然也是递归,但是如果用迭代来实现回溯法的话,是很费劲的,因为回溯的过程需要用栈模拟出来非常麻烦。

这也是为什么我在后面讲解回溯算法的时候,都是使用递归,也没有人会有栈模拟回溯算法(自己找麻烦,哈哈)。