题目地址: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; } };