題目:輸入一顆二叉樹和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。
首先想到了遞歸的方法,針對左右子樹不斷進行節點和的判斷。同時要有變量來存儲路徑和節點和,“後入先出”可以選擇棧或者vector,節點和只需要一個整型變量用來存儲即可,
因爲路徑是從根節點出發到葉節點,也就是說路徑總是以根節點爲起始點,因此我們需要遍歷根節點。在樹的前序、中序、後序3種遍歷方式中,只有前序遍歷是首先訪問根節點的。從二叉樹節點的定義看出,本題的二叉樹節點中沒有指向父節點的指針,所以需要把經過的路徑上的節點保存下來。每訪問一個節點,我們都把當前節點保存到路徑中。每次當從子節點回到父節點的時候,我們都需要在路徑上刪除子節點。
按照我之前的想法,只要當前節點的路徑使和滿足要求,就可以停止往當前節點的子節點遍歷,但討論區看到一個網友的話覺得很有道理,題目並沒有說明節點的正負,如果有節點是負的,後面子節點就還要繼續遍歷下去。
方法一:sum= sum- 當前節點->val 遞歸判斷下一個節點值與sum是否相等(這種方法參考討論區的大神,一般人的想法可能都是將節點值想加,看獲得的sum是否與指定的數值相同。)4ms 486K
class Solution {
public:
//全局變量
vector<vector<int>> res;
vector<int> path;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
find(root,expectNumber);
return res;
}
void find(TreeNode* root,int sum){
if(root == NULL){
return;
}
path.push_back(root->val);
if(!root->left && !root->right && sum == root->val){
res.push_back(path);
}
else{
if(root->left){
find(root->left,sum - root->val);
}
if(root->right){
find(root->right,sum - root->val);
}
}
path.pop_back();
}
};
方法二:同上述方法的思路一樣,但沒有另外寫子函數,都在FindPath中完成.3ms,616K
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root == NULL){
return res;
}
path.push_back(root->val);
if((expectNumber-root->val) == 0 && root->left == NULL && root->right == NULL){
res.push_back(path);
}
else{
if(root->left) FindPath(root->left,expectNumber-root->val);
if(root->right) FindPath(root->right,expectNumber-root->val);
}
if(!path.empty()){
path.pop_back();
}
return res;
}
};