面试题34:二叉树中和为某一值的路径(C++)

题目地址:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/

题目描述

输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

题目示例

示例:
给定如下二叉树,以及目标和 sum = 22,

      5
      /     
    4        8
   /         /
  11      13  4
  /            /
 7   2        5  1
返回:

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

解题思路

思路1:首先分析题目,发现可以利用先序遍历实现,即“根元素->左子树->右子树”,在先序遍历实现时,我们使用path记录根节点到当前节点的路径,如果当前节点的路径中的各元素值恰好等于目标值sum时,则将此路径加入到结果集res中,递归左右子树,向上回溯。需要注意的是,如果要将此路径加入到结果集中的条件,即当前节点为叶子节点且路径各元素值恰好等于sum值。

思路2:利用中序遍历以及栈的方法解决,思路先序遍历差不多,需要注意的是中序遍历顺序是“左子树 ->根节点 ->右子树”。

程序源码

先序遍历+回溯(递归)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    vector<vector<int>> res; //存储决策路径
    vector<int> path; //存储决策元素值
public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        if(root == nullptr) return {};
        prior_sort(root, sum);
        return res;
    }
    void prior_sort(TreeNode* root, int sum)
    {
        if(root == nullptr) return;
        path.push_back(root->val); //1.加入决策路径path
        sum -= root->val; //更新sum值
        if(sum == 0 && root->left == nullptr && root->right == nullptr) //2.找到可行解,加入结果集中
        {
            res.push_back(path);
        }
        //3.进入下一次决策
        prior_sort(root->left, sum);
        prior_sort(root->right, sum);
        path.pop_back(); //4.移出决策路径,即向上回溯,将当前节点从路径path中移出
    }
};

中序遍历+非递归

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {

public:
    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        if(root == nullptr) return {};
        stack<TreeNode*> sk;
        TreeNode* node = root, *prev_node = nullptr; //prev_node表示上一已被访问节点
        vector<vector<int>> res; //存储决策路径
        vector<int> path; //存储决策元素值
        int tmp_sum = 0;
        while(!sk.empty() || node != nullptr)
        {
            if(node != nullptr)
            {
                tmp_sum += node->val;
                path.push_back(node->val);
                sk.push(node);
                node = node->left; //一直往左遍历左子树
            }
            else
            {
                node = sk.top(); //不能往左了,取得根节点
                if(node->right == nullptr || node->right == prev_node)
                {
                    if(node->left == nullptr && node->right == nullptr && tmp_sum == sum)
                    {
                        res.push_back(path);
                    }
                    path.pop_back();
                    tmp_sum -= node->val;
                    sk.pop();
                    prev_node = node; //标记已使用
                    node = nullptr; //回溯
                }
                else
                {
                    node = node->right; //往右遍历右子树
                }
            }
        }
    return res;
    }
};
----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
原文地址:https://www.cnblogs.com/wzw0625/p/12862741.html