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