题目描述
输入一颗二叉树的根节点和一个整数,按字典序打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
题解
题目抽象:给定一颗二叉树,找出满足从根节点到叶子节点和为sun的所有路径。
如图:
方法:递归
前置知识:
-
首先清楚叶子的表示:如果节点为
root
, 那么当前节点为叶子节点的必要条件为!root->left && !root->right
-
找出路径,当然需要遍历整棵树,这里采用先序遍历,即:
根节点,左子树,右子树
代码如下:
void preOrder(TreeNode *root) {
// process root
if (root->left) preOrder(root->left);
if (root->right) preOrder(root->right);
}
具备了上面两个前置知识后,这里无非增加了路径和sum 和 叶子节点的判断。
递归算法三部曲:
- 明白递归函数的功能:
FindPath(TreeNode* root,int sum)
,从root节点出发,找和为sum的路径 - 递归终止条件:当root节点为叶子节点并且
sum==root->val
, 表示找到了一条符合条件的路径 - 下一次递归:如果左子树不空,递归左子树
FindPath(root->left, sum - root->val)
,如果右子树不空,递归右子树,FindPath(root->right, sum - root->val)
但是,你可能会问,这里没有保存路径啊?是的,可以用两个全局变量vector<int> path, vector<vector<int>> ret
来保存
class Solution {
public:
void dfs(TreeNode* root, int sum, vector<int> &path, vector<vector<int>> &ret){
path.push_back(root->val);
if(sum == root->val && !root->left && !root->right)
ret.push_back(path);
if(root->left)
dfs(root->left, sum-root->val, path, ret);
if(root->right)
dfs(root->right, sum-root->val, path, ret);
path.pop_back();
}
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
vector<vector<int>> ret;
vector<int> path;
if(!root)
return ret;
dfs(root, expectNumber, path, ret);
return ret;
}
};