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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 257. 二叉树的所有路径 思考分析

發布時間:2023/12/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 257. 二叉树的所有路径 思考分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

    • 題目
    • 思路一:深度遞歸
    • 思路二:廣度迭代
    • 關于回溯

題目

給定一個二叉樹,返回所有從根節點到葉子節點的路徑。

說明: 葉子節點是指沒有子節點的節點。

示例:

輸入:

輸出: [“1->2->5”, “1->3”]

解釋: 所有根節點到葉子節點的路徑為: 1->2->5, 1->3

思路一:深度遞歸

void traversal(TreeNode* cur , vector<string>& paths,string path){if(cur == NULL) return;path+=to_string(cur->val);//如果是葉子結點,返回將path送入paths,然后return回去if(!cur->left && !cur->right){paths.push_back(path);}//如果不是葉子結點,將該結點加入路徑,然后繼續遍歷左右子結點else{path+= "->";traversal(cur->left,paths,path);traversal(cur->right,paths,path);}return;}

之前我一直在思考一個問題,就是如果我已經完成了一條路徑,那么必定要向上回溯到上面的結點,那么此時的path又該是怎樣的呢?
在我一開始的認為中,path會直接在原有的已完成的一條路徑上再次添加->,但仔細一想,并不是這樣。
以下面的樹為例:

1
/ \
2 3
\
5

遍歷的結點輸入前的path輸入后的pathpaths
11->
21->1->2->
2的左孩子NULL1->2->1->2->
51->2->1->2->51->2->5
2(return的時候,返回到原來的函數,參數仍然是原來函數的參數)1->1->21->2->5
1(return的時候,返回到原來的函數,參數仍然是原來函數的參數)1->1->2->5
31->1->31->2->5,1->3
1(return的時候,返回到原來的函數,參數仍然是原來函數的參數)1->1->2->5,1->3

最后return根結點。

返回到上一級的時候path會被重置為上一級函數的path,而vector中的值不會被修改,因為我們使用的是&,vector中的值已經被修改了。

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:void traversal(TreeNode* cur , vector<string>& paths,string path){if(cur == NULL) return;path+=to_string(cur->val);//如果是葉子結點,返回將path送入paths,然后就該if(!cur->left && !cur->right){paths.push_back(path);}//如果不是葉子結點,將該結點加入路徑,然后繼續遍歷左右子結點else{path+= "->";traversal(cur->left,paths,path);traversal(cur->right,paths,path);}return;}vector<string> binaryTreePaths(TreeNode* root) {vector<string> paths;string path ="";traversal(root,paths,path);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 { public:vector<string> binaryTreePaths(TreeNode* root) {vector<string> paths;if(root == NULL){return paths;}queue<TreeNode*> node_queue;queue<string> path_queue;node_queue.push(root);path_queue.push(to_string(root->val));while(!node_queue.empty()){TreeNode* node = node_queue.front();string path = path_queue.front();node_queue.pop();path_queue.pop();if(node->left == NULL && node->right == NULL){paths.push_back(path);}else{if(node->left !=NULL){node_queue.push(node->left);path_queue.push(path+"->"+to_string(node->left->val));}if(node->right !=NULL){node_queue.push(node->right);path_queue.push(path+"->"+to_string(node->right->val));}}}return paths;} };

關于回溯

class Solution { public:void traversal(TreeNode* cur,vector<int>& path,vector<string>& paths){path.push_back(cur->val);//如果是葉子結點if(cur->left == NULL && cur->right ==NULL){string spath;for(int i=0;i<path.size()-1;i++){spath+= to_string(path[i]);spath+="->";}spath+=to_string(path[path.size()-1]);paths.push_back(spath);}//不是葉子結點if(cur->left){traversal(cur->left,path,paths);path.pop_back();//回溯}if(cur->right){traversal(cur->right,path,paths);path.pop_back();//回溯}}vector<string> binaryTreePaths(TreeNode* root) {vector<string> paths;vector<int> path;if(root == NULL) return paths;traversal(root,path,paths);return paths;} };

注意這里對子路徑path使用了&,所以一旦改變之后,就無法返回到上一個函數的參數了,所以需要進行pop_back進行回溯。

總結

以上是生活随笔為你收集整理的LeetCode 257. 二叉树的所有路径 思考分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。