week 3 7月14日
路徑總和II
?
給你二叉樹的根節(jié)點(diǎn) root 和一個(gè)整數(shù)目標(biāo)和 targetSum ,找出所有 從根節(jié)點(diǎn)到葉子節(jié)點(diǎn) 路徑總和等于給定目標(biāo)和的路徑。
葉子節(jié)點(diǎn) 是指沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn)。
示例 1:
輸入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
輸出:[[5,4,11,2],[5,8,4,5]]
示例 2:
輸入:root = [1,2,3], targetSum = 5
輸出:[]
示例 3:
輸入:root = [1,2], targetSum = 0
輸出:[]
提示:
樹中節(jié)點(diǎn)總數(shù)在范圍 [0, 5000] 內(nèi)
-1000 <= Node.val <= 1000
-1000 <= targetSum <= 1000
關(guān)鍵詞1:從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)
關(guān)鍵詞2:路徑總和
任務(wù):
找到所有從根節(jié)點(diǎn)到葉節(jié)點(diǎn),路徑總和為targetsum的路徑,并輸出。
任務(wù)1:遍歷所有從根節(jié)點(diǎn)到葉節(jié)點(diǎn)的路徑
任務(wù)2:找到路徑總和為targetsum的路徑,并輸出
任務(wù)1:
遍歷所有從根節(jié)點(diǎn)到葉節(jié)點(diǎn)的路徑。顯而易見(jiàn),就是遍歷二叉樹。我們采用以遞歸調(diào)用來(lái)進(jìn)行深度遍歷的方法。
當(dāng)我們?cè)L問(wèn)到某個(gè)節(jié)點(diǎn)p時(shí),有以下步驟
?1、若p為空,則返回p的上一層節(jié)點(diǎn);若不為空,則進(jìn)行步驟2、3
?1、訪問(wèn)p的左子樹,若左子樹為空,則返回上一層節(jié)點(diǎn)p;若左子樹不為空,對(duì)左子樹進(jìn)行重復(fù)步驟2、3
?2、訪問(wèn)p的右子樹,若右子樹為空,則返回上一層節(jié)點(diǎn)p;若右子樹不為空,對(duì)右子樹進(jìn)行重復(fù)步驟2、3
舉例如下:
黑色箭頭表示向下訪問(wèn)左子樹或者右子樹;紅色箭頭表示訪問(wèn)結(jié)束,返回上層節(jié)點(diǎn)?
代碼如下:
void dfs(TreeNode *p, int targetSum) {if(p==nullptr){return ;}//若該節(jié)點(diǎn)為空節(jié)點(diǎn),返回上一層dfs(p->left,targetSum);//訪問(wèn)該節(jié)點(diǎn)的左孩子dfs(p->right,targetSum);//訪問(wèn)該節(jié)點(diǎn)的右孩子 }任務(wù)2:
找到路徑總和為targetsum的路徑,并輸出。在任務(wù)1的遍歷中,通過(guò)深度遍歷找到了所有路徑。所以在任務(wù)2中,只需要在遍歷時(shí),維護(hù)一個(gè)全局變量,當(dāng)前路徑和sum,來(lái)判斷是否滿足targetsum的條件即可。若滿足,返回當(dāng)時(shí)該路徑;若不滿足,則繼續(xù)遍歷。
為完整輸出二維結(jié)果,還需要維護(hù)兩個(gè)數(shù)組。臨時(shí)數(shù)組temp,用于當(dāng)前遍歷到的數(shù)組存儲(chǔ)。最終結(jié)果數(shù)組result,用于存儲(chǔ)達(dá)到路徑要求和葉子節(jié)點(diǎn)的temp數(shù)組。
具體步驟如下:
?1、訪問(wèn)節(jié)點(diǎn)p。若p為空,則返回p的上一層節(jié)點(diǎn),并且把當(dāng)前節(jié)點(diǎn)的值從sum中去掉,并且從temp中彈出當(dāng)前節(jié)點(diǎn);若不為空,將p的值加入到全局變量sum中,并把當(dāng)前節(jié)點(diǎn)存入臨時(shí)數(shù)組temp中。如果加入p值后,sum的值等于targesum并且p為葉子節(jié)點(diǎn),則將temp存入最終數(shù)組result。如果p不是葉子節(jié)點(diǎn),則進(jìn)行步驟2、3
?2、訪問(wèn)p的左子樹,重復(fù)步驟1
?2、訪問(wèn)p的右子樹,重復(fù)步驟1
具體流程如下所示:
黑色箭頭表示向下訪問(wèn)左子樹或者右子樹;紅色箭頭表示訪問(wèn)結(jié)束,返回上層節(jié)點(diǎn)?
?完整代碼如下所示:
class Solution { public:vector<vector<int>> result;//最終數(shù)組vector<int> temp;//臨時(shí)數(shù)組int sum=0;vector<vector<int>> pathSum(TreeNode* root, int targetSum) {dfs(root,targetSum);return result;}void dfs(TreeNode *p, int targetSum){if(p==nullptr){return ;}//如果該節(jié)點(diǎn)為空,返回上一層sum+=p->val;temp.push_back(p->val);if(targetSum==sum&&p->left==nullptr&&p->right==nullptr)//當(dāng)路徑總和相同,并且p節(jié)點(diǎn)是葉子節(jié)點(diǎn)時(shí){result.push_back(temp);}dfs(p->left,targetSum);dfs(p->right,targetSum);sum-=p->val;//返回上層后,需把剛才那層算進(jìn)去的路徑和值去掉temp.pop_back();//返回上一層后,需要把剛才那層的節(jié)點(diǎn)彈出去} };路徑總和III
給定一個(gè)二叉樹的根節(jié)點(diǎn) root?和一個(gè)整數(shù) targetSum ,求該二叉樹里節(jié)點(diǎn)值之和等于 targetSum 的 路徑 的數(shù)目。
路徑不需要從根節(jié)點(diǎn)開(kāi)始,也不需要在葉子節(jié)點(diǎn)結(jié)束,但是路徑方向必須是向下的(只能從父節(jié)點(diǎn)到子節(jié)點(diǎn))。
示例 1:
輸入:root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
輸出:3
解釋:和等于 8 的路徑有 3 條,如圖所示。
示例 2:
輸入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
輸出:3
提示:
二叉樹的節(jié)點(diǎn)個(gè)數(shù)的范圍是 [0,1000]
-109?<= Node.val <= 109?
-1000?<= targetSum?<= 1000
關(guān)鍵詞1:路徑之和
關(guān)鍵詞2:不需要從根節(jié)點(diǎn)開(kāi)始,也不需要在葉子節(jié)點(diǎn)結(jié)束
任務(wù):
找到一條路徑,該路徑之和為targetsum,并且該路徑的起點(diǎn)不一定是根節(jié)點(diǎn),終點(diǎn)也不一定是葉子節(jié)點(diǎn)
任務(wù)1:對(duì)于一個(gè)節(jié)點(diǎn),得到其下路徑之和為targetsum的路徑數(shù)
任務(wù)2:找到所有滿足任務(wù)1條件的節(jié)點(diǎn),求得路徑數(shù)
任務(wù)1:
對(duì)于某一個(gè)特定的節(jié)點(diǎn),求路徑之和。是上一個(gè)作業(yè)路徑之和II的內(nèi)容。不在贅述。維護(hù)一個(gè)變量sum,用以記錄該子樹的路徑總數(shù)。在子樹中,遇到滿足條件的路徑,sum+1。詳情參考文章第一段。
任務(wù)2:
找到所有滿足任務(wù)1條件的節(jié)點(diǎn),求得路徑數(shù)。其實(shí)就是遍歷所有的節(jié)點(diǎn),在得到該節(jié)點(diǎn)后對(duì)路徑數(shù)相加。
class Solution { public:int dfs(TreeNode* root, long targetSum) {//對(duì)于某一子樹來(lái)說(shuō),求得其滿足條件路徑總數(shù)if (!root) {return 0;}int sum = 0;if (root->val == targetSum) {sum++;} sum += dfs(root->left, targetSum - root->val);sum += dfs(root->right, targetSum - root->val);return sum;}int pathSum(TreeNode* root, int targetSum) {if (!root) {return 0;} int sum = dfs(root, targetSum); //先以根節(jié)點(diǎn)為固定節(jié)點(diǎn),計(jì)算其路徑總數(shù)sum += pathSum(root->left, targetSum);//計(jì)算以左子樹為固定節(jié)點(diǎn)的路徑總數(shù)sum += pathSum(root->right, targetSum);//計(jì)算以右子樹為固定節(jié)點(diǎn)的路徑總數(shù)return sum;} };總結(jié)
以上是生活随笔為你收集整理的week 3 7月14日的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 67.深度解密网络项目五:线上和线下营销
- 下一篇: jQuery移动端拖动div