日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 112. 路径总和 、113. 路径总和 II 思考分析

發(fā)布時(shí)間:2023/12/1 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 112. 路径总和 、113. 路径总和 II 思考分析 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

  • 112. 路徑總和
    • 題目
    • 遞歸解
    • 遞歸解,其他人的解法
    • 迭代解,其他人的解法
  • 113. 路徑總和 II
    • 題目
    • 遞歸解
    • 遞歸解,參考別人的思路

112. 路徑總和

題目

給定一個(gè)二叉樹(shù)和一個(gè)目標(biāo)和,判斷該樹(shù)中是否存在根節(jié)點(diǎn)到葉子節(jié)點(diǎn)的路徑,這條路徑上所有節(jié)點(diǎn)值相加等于目標(biāo)和。

說(shuō)明: 葉子節(jié)點(diǎn)是指沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn)。

示例:
給定如下二叉樹(shù),以及目標(biāo)和 sum = 22,

返回 true, 因?yàn)榇嬖谀繕?biāo)和為 22 的根節(jié)點(diǎn)到葉子節(jié)點(diǎn)的路徑 5->4->11->2。

遞歸解

1、函數(shù)參數(shù):當(dāng)前樹(shù)的根結(jié)點(diǎn)、當(dāng)前累積的路徑和,目標(biāo)路徑和;返回值為空
2、終止條件:該結(jié)點(diǎn)為空
3、單層邏輯:如果該結(jié)點(diǎn)不為空,則在累積路徑和上加上該結(jié)點(diǎn)的值。如果該結(jié)點(diǎn)是葉子結(jié)點(diǎn),判斷此時(shí)的累積路徑和與目標(biāo)路徑和是否相同,如果相同則將全局變量ifHas改為true,認(rèn)為能夠找到路徑和為目標(biāo)值的路徑。然后返回父結(jié)點(diǎn),回溯到上一個(gè)狀態(tài),參數(shù)會(huì)自動(dòng)更正為上一個(gè)狀態(tài)的參數(shù)。接下來(lái)就是按順序?qū)υ摻Y(jié)點(diǎn)的左右孩子進(jìn)行遍歷

這個(gè)思路是有問(wèn)題的,因?yàn)樗辉谌~子結(jié)點(diǎn)之后才回溯,這是不合理的,但是也能AC。

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:bool ifHas=false;void traversal(TreeNode* cur,int target,int Mysum){if(cur==NULL) return;if(cur!=NULL) Mysum+=cur->val;//如果是葉子結(jié)點(diǎn),則進(jìn)行比較if(cur->left==NULL && cur->right==NULL){//如果和目標(biāo)結(jié)果相同if(Mysum == target) ifHas=true;return;}if(cur->left){traversal(cur->left,target,Mysum);}if(cur->right){traversal(cur->right,target,Mysum);}return ;}bool hasPathSum(TreeNode* root, int sum) {//if(root == NULL) return false;int Mysum=0;traversal(root,sum,Mysum);return ifHas;} };

遞歸解,其他人的解法

1、函數(shù)參數(shù)、返回值確定
之前有個(gè)結(jié)論:如果需要搜索整棵二叉樹(shù),那么遞歸函數(shù)就不要返回值,如果要搜索其中一條符合條件的路徑,遞歸函數(shù)就需要返回值,因?yàn)橛龅椒蠗l件的路徑就要及時(shí)返回。
本題并不需要遍歷整棵樹(shù),所以遞歸函數(shù)需要返回值,可以用bool類(lèi)型表示。

bool traversal(TreeNode* cur,int count)

2、終止條件確定
在如何統(tǒng)計(jì)一條路徑和的方法上,代碼隨想錄使用遞減的方法,讓計(jì)數(shù)器count初始為目標(biāo)和,然后每次減去遍歷路徑結(jié)點(diǎn)上的數(shù)值。如果最后count==0,同時(shí)到了葉子結(jié)點(diǎn)的話(huà),說(shuō)明了找到目標(biāo)和。如果遍歷到了葉子結(jié)點(diǎn),cout不為0,就是沒(méi)找到

if(!cur->left && !cur->right && count == 0) return true; //遇到葉子結(jié)點(diǎn),并且計(jì)數(shù)為0 if(!cur->left && !cur->right) return false; //遇到葉子結(jié)點(diǎn),沒(méi)有找到合適的邊,直接返回

3、確定單層遞歸的邏輯
因?yàn)榻K止條件是判斷也自己誒單,所以遞歸過(guò)程中就不要讓空結(jié)點(diǎn)進(jìn)入遞歸了。
遞歸函數(shù)的返回值為true的話(huà)說(shuō)明了找到了合適的路徑,應(yīng)該立刻返回

if(cur->left) {count -=cur->left->val;//遇到葉子結(jié)點(diǎn)返回true,則直接返回true;if(traversal(cur->left,count)) return true;count +=cur->left->val; //回溯,撤銷(xiāo)處理結(jié)果 } if(cur->right) {count -=cur->right->val;//遇到葉子結(jié)點(diǎn)返回true,則直接返回true;if(traversal(cur->right,count)) return true;count +=cur->right->val; //回溯,撤銷(xiāo)處理結(jié)果 } return false; class Solution { public:bool traversal(TreeNode* cur,int count) {if(!cur->left && !cur->right && count == 0) return true; //遇到葉子結(jié)點(diǎn),并且計(jì)數(shù)為0if(!cur->left && !cur->right) return false; //遇到葉子結(jié)點(diǎn),沒(méi)有找到合適的邊,直接返回if(cur->left){count -=cur->left->val;//遇到葉子結(jié)點(diǎn)返回true,則直接返回true;if(traversal(cur->left,count)) return true;count +=cur->left->val; //回溯,撤銷(xiāo)處理結(jié)果}if(cur->right){count -=cur->right->val;//遇到葉子結(jié)點(diǎn)返回true,則直接返回true;if(traversal(cur->right,count)) return true;count +=cur->right->val; //回溯,撤銷(xiāo)處理結(jié)果}return false;}bool hasPathSum(TreeNode* root, int sum) {if(root == NULL) return false;return traversal(root,sum-root->val);} };

迭代解,其他人的解法

如果使用棧模擬遞歸的話(huà)對(duì)于回溯如何處理?
此時(shí)棧里面的一個(gè)元素不僅要記錄該結(jié)點(diǎn)指針,還要記錄從頭結(jié)點(diǎn)到該結(jié)點(diǎn)的路徑數(shù)值總和。
這里使用pair結(jié)構(gòu)來(lái)存放棧里面的元素。(第一次用這個(gè)結(jié)構(gòu))
定義為:

pair<TreeNode*,int> pair<結(jié)點(diǎn)指針,路徑數(shù)值>

為棧中的一個(gè)元素。
使用棧模擬前序遍歷;

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:bool hasPathSum(TreeNode* root, int sum) {if(root == NULL) return false;//此時(shí)棧里面要放的是pair<結(jié)點(diǎn)指針,路徑數(shù)值>stack<pair<TreeNode*,int>> st;st.push(pair<TreeNode*,int>(root,root->val));while(!st.empty()){pair<TreeNode*,int> node = st.top();st.pop();//如果這個(gè)結(jié)點(diǎn)是葉子結(jié)點(diǎn),同時(shí)該結(jié)點(diǎn)的路徑數(shù)值等于sum,那么就返回trueif(!node.first->left &&!node.first->right && sum == node.second ) return true;//右結(jié)點(diǎn),壓進(jìn)去一個(gè)結(jié)點(diǎn)的時(shí)候,將該結(jié)點(diǎn)的路徑數(shù)值也記錄下來(lái)if(node.first->right){st.push(pair<TreeNode*,int>(node.first->right,node.second+node.first->right->val));}//右結(jié)點(diǎn),壓進(jìn)去一個(gè)結(jié)點(diǎn)的時(shí)候,將該結(jié)點(diǎn)的路徑數(shù)值也記錄下來(lái)if(node.first->left){st.push(pair<TreeNode*,int>(node.first->left,node.second+node.first->left->val));}}return false;} };

113. 路徑總和 II

題目

給定一個(gè)二叉樹(shù)和一個(gè)目標(biāo)和,找到所有從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)路徑總和等于給定目標(biāo)和的路徑。

說(shuō)明: 葉子節(jié)點(diǎn)是指沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn)。

遞歸解

同樣的道理,Mysum作為函數(shù)參數(shù)每次返回的時(shí)候會(huì)自動(dòng)更正,不需要手動(dòng)回溯。
完成一次子結(jié)果,就將子結(jié)果送入paths中。
path需要手動(dòng)回溯。

path.push_back(cur->left->val);traversal(cur->left,target,Mysum);path.pop_back();

同時(shí)需要注意,在一開(kāi)始要將根結(jié)點(diǎn)送入path中,因?yàn)樵谖覀兊倪f歸函數(shù)中只對(duì)左右孩子進(jìn)行push_back()

class Solution { public:vector<vector<int>> paths;vector<int> path;void traversal(TreeNode* cur,int target,int Mysum){if(cur==NULL) return;if(cur!=NULL){Mysum+=cur->val;} //如果是葉子結(jié)點(diǎn),則進(jìn)行比較if(cur->left==NULL && cur->right==NULL){//如果和目標(biāo)結(jié)果相同if(Mysum == target){paths.push_back(path);}return;}if(cur->left){path.push_back(cur->left->val);traversal(cur->left,target,Mysum);path.pop_back();}if(cur->right){path.push_back(cur->right->val);traversal(cur->right,target,Mysum);path.pop_back();}return ;}vector<vector<int>> pathSum(TreeNode* root, int sum) {if(root==NULL) return {};int Mysum=0;path.push_back(root->val);traversal(root,sum,Mysum);return paths;} };

遞歸解,參考別人的思路

/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { private:vector<vector<int>> paths;vector<int> path;//遞歸函數(shù)不需要返回值,因?yàn)槲覀円闅v整個(gè)樹(shù)void traversal(TreeNode* cur,int count){if(!cur->left && !cur->right && count == 0) //遇到了葉子結(jié)點(diǎn)且找到了和為sum的路徑{paths.push_back(path);return;}if(!cur->left && !cur->right ) return;if(cur->left){path.push_back(cur->left->val);count-=cur->left->val;traversal(cur->left,count);count+=cur->left->val;path.pop_back();}if(cur->right){path.push_back(cur->right->val);count-=cur->right->val;traversal(cur->right,count);count+=cur->right->val;path.pop_back();}return;} public:vector<vector<int>> pathSum(TreeNode* root, int sum) {paths.clear();path.clear();if(root==NULL) return paths;path.push_back(root->val);traversal(root,sum-root->val);return paths;} };

工程實(shí)踐上一定要clear,但是由于力扣后臺(tái)測(cè)試數(shù)據(jù),每次都是新new一個(gè)對(duì)象

總結(jié)

以上是生活随笔為你收集整理的LeetCode 112. 路径总和 、113. 路径总和 II 思考分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。