題目:node
輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和爲輸入整數的全部路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所通過的結點造成一條路徑。ide
例如輸入下圖中二叉樹和整數22,則打印出兩條路徑,第一條路徑包含結點十、12,第二條路徑包含結點十、5和7。spa
思路:orm
一、判斷根結點是否爲空遞歸
二、單一路徑要有vector<int> path保存;it
三、多條路徑要有vector<vector<int>> ret保存並返回;io
四、從根結點分析,因爲每次遍歷都要先把結點的值進行訪問因此是前序遍歷;class
五、在遍歷的同時,須要保存訪問過結點的值,而且和expectNumber相減獲得剩餘expectNumber二叉樹
六、只有根結點才用判斷最後的值和剩餘expectnumber相等,不相等,pop出path遍歷
七、根結點相等即爲遞歸退出條件
代碼:
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { vector<vector<int>> ret; vector<int> path; if(root==NULL) { return ret; } findLeaf(ret,path,root,expectNumber); return ret; } void findLeaf(vector<vector<int>> &ret,vector<int> &path,TreeNode *node,int left) { path.push_back(node->val); //終止條件 if(left-node->val==0&&node->left==NULL&&node->right==NULL) { ret.push_back(path); } else { if(node->left) { int l=left-node->val; findLeaf(ret,path,node->left,l); } if(node->right) { int l=left-node->val; findLeaf(ret,path,node->right,l); } } //是葉子節點可是路徑和不同,pop這個葉子節點 path.pop_back(); } };
精簡版代碼:
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { vector<vector<int> >allRes; vector<int> tmp; void dfsFind(TreeNode * node , int left){ tmp.push_back(node->val); if(left-node->val == 0 && !node->left && !node->right) allRes.push_back(tmp); else { if(node->left) dfsFind(node->left, left-node->val); if(node->right) dfsFind(node->right, left-node->val); } tmp.pop_back(); } public: vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { if(root) dfsFind(root, expectNumber); return allRes; } };