題目:輸入一顆二叉樹和乙個整數,列印出二叉樹中結點值的和為輸入整數的所有路徑。從樹的根結點開始往下一直到葉節點所經過的結點形成一條路徑。二叉樹的定義如下:
struct treenode ;
二叉樹中我們最為熟悉操作莫過於各種遍歷了,前序遍歷(根左右),中序遍歷(左根右),後序遍歷(左右根)和層次遍歷。而真正筆試題很少會直接考察二叉樹的遍歷的,而是需要我們會利用二叉樹的遍歷解決相關問題。最近因為這題思考良久,一直沒得出合理的解決方案。期間反映出我對二叉樹的操作還是很不熟悉!
對於上圖和為20的路徑包括,和。為了找出這些路徑,我們來分析一下尋找流程,並盡量用上我們熟悉的二叉樹遍歷。由於需要的路徑是從根節點到葉子節點列印,感覺上符合前序遍歷!先走一遍,首先我們需要乙個容器儲存路徑arr和乙個遍歷儲存路徑的節點和curnumber
1.遇到根節點10,將10放到路徑中,curnumber = 10,此時路徑為;
2.左結點不為空,訪問左結點8,8儲存到路徑中,curnumber = 10+8 = 18,此時路徑為;
3.左結點不為空,繼續訪問左結點5,5儲存到路徑中,curnumber = 18+5 = 23,此時路徑為;
4.左右結點都為空,說明該節點為葉子結點,檢查當前的路徑值curnumber != 20,不是需要的路徑不儲存;
5.此時需要返回,刪除路徑中的末尾結點5,同時路徑和減去末尾結點值5,回到結點8,curnumber = 18,此時結點路徑為;
6.結點8的右子樹不為空,訪問右結點2,將2放到路徑中,curnumber = 18+2 = 20,此時路徑為;
7.結點2的左右子樹都為空,結點2為葉子結點,當前的curnumber == 20,說明此時的路徑為我需要的路徑!將此時的路徑儲存起來(或者直接列印);當前路徑中刪除節點2,curnumber 減去當前節點的值2,返回到節點8;
8.繼續將結點8從當前路徑中刪除,當前路徑值減去8,則當前路徑為,路徑值為10;
9.訪問結點10的右子樹。。。
觀察上述過程和前序遍歷完全一致,只是中間多了路徑的儲存和路徑值的判斷。根據上述思想,我們可以得到下面的**:
vector> findpath(treenode* root,int expectnumber)
void findvalidpath(treenode* root,int expectnumber,vector>& patharr,
vector&curpath,int& curnumber)
curpath.pop_back(); //最後乙個節點出棧
curnumber -= root->val;
return;
}findvalidpath(root->left,expectnumber,patharr,curpath,curnumber); //處理左子樹
findvalidpath(root->right,expectnumber,patharr,curpath,curnumber); //處理右子樹
curpath.pop_back(); //對處理完的非葉子節點出棧,並更新當前路徑和路徑值
curnumber -= root->val;
}
牛客網(本文講的題目在該**上也能
找到。
二叉樹中和為某一值的路徑
include include using namespace std struct node void find path node r,int exceptedsum,vector path,int cursum node buildbtree int a,int i void preorder...
二叉樹中和為某一值的路徑
要輸出所有的路徑,必須額外用乙個棧來儲存當前路徑資訊。當訪問到節點a時,節點a的資訊要在訪問a的左右子樹時用到,因而,該資訊必須在遍歷a的左右子樹前加入到棧中,而在遍歷完a的左右子樹後從棧中移除。每訪問乙個節點,就計算當前路徑值 可直接利用父節點的路徑值 當其等於給定值且當前節點是葉子節點時,就列印...
二叉樹中和為某一值的路徑
面試題25 二叉樹中和為某一值的路徑 struct binarytreenode int value binarytreenode pleft binarytreenode pright 分析 用先序遍歷的方式遍歷二叉樹,初始時路徑為空。訪問乙個結點時若不到葉子結點且結點的和小於這個值那麼就把這個結...