(剑指Offer)面试题25:二叉树中和为某一值的路径
题目:
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
二叉树结点的定义:
struct TreeNode{ int val; TreeNode* left; TreeNode* right; };
思路:
典型的回溯法问题,主要分为递归和剪枝两部分。
递归:
如果当前结点不为空,且结点的值小于期望值,则将该结点压入路径vector中,并继续从左右子结点往下遍历;
if(root->left) FindPath(root->left,result,path,expectedNumber-root->val);
if(root->right) FindPath(root->right,result,path,expectedNumber-root->val);
递归的结束条件:
当遍历到了叶子节点,且该叶子结点的值等于期望值,那么这是一条满足的路径;
剪枝:
如果当前结点的值大于期望值,那么往下遍历已经没有意义了,于是返回,避免一些无谓的计算;
代码:
void FindPath(TreeNode* pRoot,vector<int> &path,int expectedSum){ if(pRoot->val>expectedSum) return; path.push_back(pRoot->val); if(pRoot->left==NULL && pRoot->right==NULL && pRoot->val==expectedSum){ printf("A path is found: "); for(std::vector<int>::iterator it=path.begin();it!=path.end();it++) printf("%d\t",*it); printf("\n"); return; } if(pRoot->left) FindPath(pRoot->left,path,expectedSum-pRoot->val); if(pRoot->right) FindPath(pRoot->right,path,expectedSum-pRoot->val); path.pop_back(); } void FindPath(TreeNode* pRoot,int expectedSum){ if(pRoot==NULL) return; std::vector<int> path; FindPath(pRoot,path,expectedSum); }
在线测试OJ:
http://www.nowcoder.com/books/coding-interviews/b736e784e3e34731af99065031301bca?rp=1
AC代码:
class Solution { public: vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { vector<vector<int> > result; if(root==NULL) return result; vector<int> path; FindPath(root,result,path,expectNumber); return result; } void FindPath(TreeNode* root,vector<vector<int> > &result,vector<int> &path,int expectedNumber){ if(root->val>expectedNumber) return; path.push_back(root->val); bool isLeaf=root->left==NULL && root->right==NULL; if(isLeaf && root->val==expectedNumber){ result.push_back(path); path.pop_back(); return; } if(root->left) FindPath(root->left,result,path,expectedNumber-root->val); if(root->right) FindPath(root->right,result,path,expectedNumber-root->val); path.pop_back(); } };