題目描述:
輸入一顆二叉樹的跟節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。
解題思路:
本題利用先序遍歷訪問某一節點的值,並且將該節點添加到當前路徑序列中,此外累加該節點的值;如果當前節點是葉子節點,則判斷當前路徑中的值是否等於期望值,如果等於則輸出該路徑;如果當前節點不是葉子節點,則繼續訪問該節點的左右子節點;如果在左右子節點中都沒有找到滿足條件的路徑,則返回到當前節點的父節點,注意將當前節點從當前路徑序列中去除。
ps:當前路徑vector<int>curPath是地址傳遞,遞歸過程中共用存儲空間,所以需要將當前節點的值從當前路徑序列中去除;而curSum是值傳遞,遞歸的每一層都保留有對應的當前路徑元素和。
通過代碼(C++):
/*
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>>result;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root == nullptr)
return result;
vector<int>curPath;
int curSum = 0;
findPathWithSum(root,expectNumber,curSum,curPath);
return result;
}
void findPathWithSum(TreeNode* curNode,int expectNumber,int curSum,vector<int>curPath)
{
curSum += curNode->val;
curPath.push_back(curNode->val);
bool isLeaf = (curNode->left==nullptr) && (curNode->right==nullptr);
//該curNode節點是葉節點而且路徑上的和等於expectNumber,則爲想要的輸出結果
if(isLeaf && (curSum == expectNumber))
{
result.push_back(curPath);
return;
}
//遞歸的先序搜索左子樹,看是否有合適的值
if(curNode->left != nullptr)
findPathWithSum(curNode->left,expectNumber,curSum,curPath);
if(curNode->right != nullptr)
findPathWithSum(curNode->right,expectNumber,curSum,curPath);
//如果左右子樹都沒有滿足的路徑,則迴歸當父節點
//由於每一層遞歸調用都有自己的curSum,所以不用對curSum進行操作;
//而curPath是所有遞歸共享的,所以要將先序遍歷加入的當前節點刪除。
curPath.pop_back();
return;
}
};