C++實現(xiàn)LeetCode(113.二叉樹路徑之和之二)
[LeetCode] 113. Path Sum II 二叉樹路徑之和之二
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
For example:
Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
return
[
[5,4,11,2],
[5,8,4,5]
]
這道二叉樹路徑之和在之前那道題 Path Sum 的基礎上又需要找出路徑,但是基本思想都一樣,還是需要用深度優(yōu)先搜索 DFS,只不過數(shù)據(jù)結(jié)構(gòu)相對復雜一點,需要用到二維的 vector,而且每當 DFS 搜索到新結(jié)點時,都要保存該結(jié)點。而且每當找出一條路徑之后,都將這個保存為一維 vector 的路徑保存到最終結(jié)果二維 vector 中。并且,每當 DFS 搜索到子結(jié)點,發(fā)現(xiàn)不是路徑和時,返回上一個結(jié)點時,需要把該結(jié)點從一維 vector 中移除,參見代碼如下:
解法一:
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
vector<int> out;
helper(root, sum, out, res);
return res;
}
void helper(TreeNode* node, int sum, vector<int>& out, vector<vector<int>>& res) {
if (!node) return;
out.push_back(node->val);
if (sum == node->val && !node->left && !node->right) {
res.push_back(out);
}
helper(node->left, sum - node->val, out, res);
helper(node->right, sum - node->val, out, res);
out.pop_back();
}
};
下面這種方法是迭代的寫法,用的是中序遍歷的順序,參考之前那道 Binary Tree Inorder Traversal,中序遍歷本來是要用棧來輔助運算的,由于要取出路徑上的結(jié)點值,所以用一個 vector 來代替 stack,首先利用 while 循環(huán)找到最左子結(jié)點,在找的過程中,把路徑中的結(jié)點值都加起來,這時候取出 vector 中的尾元素,如果其左右子結(jié)點都不存在且當前累加值正好等于 sum 了,將這條路徑取出來存入結(jié)果 res 中,下面的部分是和一般的迭代中序?qū)懛ㄓ兴煌牡胤?,由于中序遍歷的特點,遍歷到當前結(jié)點的時候,是有兩種情況的,有可能此時是從左子結(jié)點跳回來的,此時正要去右子結(jié)點,則當前的結(jié)點值還是算在路徑中的;也有可能當前是從右子結(jié)點跳回來的,并且此時要跳回上一個結(jié)點去,此時就要減去當前結(jié)點值,因為其已經(jīng)不屬于路徑中的結(jié)點了。為了區(qū)分這兩種情況,這里使用一個額外指針 pre 來指向前一個結(jié)點,如果右子結(jié)點存在且不等于 pre,直接將指針移到右子結(jié)點,反之更新 pre 為 cur,cur 重置為空,val 減去當前結(jié)點,st 刪掉最后一個結(jié)點,參見代碼如下:
解法二:
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
vector<TreeNode*> st;
TreeNode *cur = root, *pre = nullptr;
int val = 0;
while (cur || !st.empty()) {
while (cur) {
st.push_back(cur);
val += cur->val;
cur = cur->left;
}
cur = st.back();
if (!cur->left && !cur->right && val == sum) {
vector<int> v;
for (auto &a : st) v.push_back(a->val);
res.push_back(v);
}
if (cur->right && cur->right != pre) {
cur = cur->right;
} else {
pre = cur;
val -= cur->val;
st.pop_back();
cur = nullptr;
}
}
return res;
}
};
到此這篇關于C++實現(xiàn)LeetCode(113.二叉樹路徑之和之二)的文章就介紹到這了,更多相關C++實現(xiàn)二叉樹路徑之和之二內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++使用郵件槽實現(xiàn)ShellCode跨進程傳輸
在計算機安全領域,進程間通信(IPC)一直是一個備受關注的話題,在本文中,我們將探討如何使用Windows郵件槽(Mailslot)實現(xiàn)ShellCode的跨進程傳輸,需要的可以參考下2023-12-12
VC6.0代碼自動提示 VC6.0在win7環(huán)境下代碼提示智能化
作為程序猿的你,是否已經(jīng)喜歡或習慣依賴IDE開發(fā)環(huán)境呢,有了IDE環(huán)境,即使你想不起方法全名,只要知道某個前綴,或哪怕在提示列表中,一一查詢,也可以找到自己想找的方法或?qū)傩?/div> 2013-01-01
Qt數(shù)據(jù)庫相關應用開發(fā)總結(jié)
這篇文章主要為大家介紹了在Qt數(shù)據(jù)庫應用開發(fā)中的一些經(jīng)驗總結(jié),以及一些組件的使用介紹。文中的示例代碼講解詳細,需要的可以參考一下2022-02-02最新評論

