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

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

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

消除左递归c++代码_「leetcode」129. 求根到叶子节点数字之和【递归中隐藏着回溯】详解...

發(fā)布時(shí)間:2023/12/19 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 消除左递归c++代码_「leetcode」129. 求根到叶子节点数字之和【递归中隐藏着回溯】详解... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

鏈接

https://leetcode-cn.com/problems/sum-root-to-leaf-numbers/

思路

本題和113.路徑總和II是類似的思路,做完這道題,可以順便把113.路徑總和II 和 112.路徑總和 做了。

結(jié)合112.路徑總和 和 113.路徑總和II,我在講了二叉樹(shù):遞歸函數(shù)究竟什么時(shí)候需要返回值,什么時(shí)候不要返回值?,如果大家對(duì)二叉樹(shù)遞歸函數(shù)什么時(shí)候需要返回值很迷茫,可以看一下。

接下來(lái)在看本題,就簡(jiǎn)單多了,本題其實(shí)需要使用回溯,但一些同學(xué)可能都不知道自己用了回溯,在二叉樹(shù):以為使用了遞歸,其實(shí)還隱藏著回溯中,我詳細(xì)講解了二叉樹(shù)的遞歸中,如何使用了回溯。

接下來(lái)我們來(lái)看題:

首先思路很明確,就是要遍歷整個(gè)樹(shù)把更節(jié)點(diǎn)到葉子節(jié)點(diǎn)組成的數(shù)字相加。

那么先按遞歸三部曲來(lái)分析:

遞歸三部曲

如果對(duì)遞歸三部曲不了解的話,可以看這里:二叉樹(shù):前中后遞歸詳解

  • 確定遞歸函數(shù)返回值及其參數(shù)

這里我們要遍歷整個(gè)二叉樹(shù),且需要要返回值做邏輯處理,所有返回值為void,在二叉樹(shù):遞歸函數(shù)究竟什么時(shí)候需要返回值,什么時(shí)候不要返回值?中,詳細(xì)講解了返回值問(wèn)題。

參數(shù)只需要把根節(jié)點(diǎn)傳入,此時(shí)還需要定義兩個(gè)全局遍歷,一個(gè)是result,記錄最終結(jié)果,一個(gè)是vector path。

「為什么用vector類型(就是數(shù)組)呢? 因?yàn)橛胿ector方便我們做回溯!」

所以代碼如下:

int result; vector<int> path; void traversal(TreeNode* cur)
  • 確定終止條件

遞歸什么時(shí)候終止呢?

當(dāng)然是遇到葉子節(jié)點(diǎn),此時(shí)要收集結(jié)果了,通知返回本層遞歸,因?yàn)閱螚l路徑的結(jié)果使用vector,我們需要一個(gè)函數(shù)vectorToInt把vector轉(zhuǎn)成int。

終止條件代碼如下:

if (!cur->left && !cur->right) { // 遇到了葉子節(jié)點(diǎn)result += vectorToInt(path);return; }

這里vectorToInt函數(shù)就是把數(shù)組轉(zhuǎn)成int,代碼如下:

int vectorToInt(const vector<int>& vec) {int sum = 0;for (int i = 0; i < vec.size(); i++) {sum = sum * 10 + vec[i];}return sum; }
  • 確定遞歸單層邏輯

本題其實(shí)采用前中后序都不無(wú)所謂, 因?yàn)橐矝](méi)有中間幾點(diǎn)的處理邏輯。

這里主要是當(dāng)左節(jié)點(diǎn)不為空,path收集路徑,并遞歸左孩子,右節(jié)點(diǎn)同理。

「但別忘了回溯」。

如圖:

代碼如下:

// 中 if (cur->left) { // 左 (空節(jié)點(diǎn)不遍歷)path.push_back(cur->left->val);traversal(cur->left); // 遞歸path.pop_back(); // 回溯 } if (cur->right) { // 右 (空節(jié)點(diǎn)不遍歷)path.push_back(cur->right->val);traversal(cur->right); // 遞歸path.pop_back(); // 回溯 }

這里要注意回溯和遞歸要永遠(yuǎn)在一起,一個(gè)遞歸,對(duì)應(yīng)一個(gè)回溯,是一對(duì)一的關(guān)系,有的同學(xué)寫成如下代碼:

if (cur->left) { // 左 (空節(jié)點(diǎn)不遍歷)path.push_back(cur->left->val);traversal(cur->left); // 遞歸 } if (cur->right) { // 右 (空節(jié)點(diǎn)不遍歷)path.push_back(cur->right->val);traversal(cur->right); // 遞歸 } path.pop_back(); // 回溯

「把回溯放在花括號(hào)外面了,世界上最遙遠(yuǎn)的距離,是你在花括號(hào)里,而我在花括號(hào)外!」 這就不對(duì)了。

整體C++代碼

關(guān)鍵邏輯分析完了,整體C++代碼如下:

class Solution { private:int result;vector<int> path;// 把vector轉(zhuǎn)化為intint vectorToInt(const vector<int>& vec) {int sum = 0;for (int i = 0; i < vec.size(); i++) {sum = sum * 10 + vec[i];}return sum;}void traversal(TreeNode* cur) {if (!cur->left && !cur->right) { // 遇到了葉子節(jié)點(diǎn)result += vectorToInt(path);return;}if (cur->left) { // 左 (空節(jié)點(diǎn)不遍歷)path.push_back(cur->left->val);traversal(cur->left); // 遞歸path.pop_back(); // 回溯}if (cur->right) { // 右 (空節(jié)點(diǎn)不遍歷)path.push_back(cur->right->val);traversal(cur->right); // 遞歸path.pop_back(); // 回溯}return ;} public:int sumNumbers(TreeNode* root) {path.clear();if (root == nullptr) return 0;path.push_back(root->val);traversal(root);return result;} };

總結(jié)

過(guò)于簡(jiǎn)潔的代碼,很容易讓初學(xué)者忽視了本題中回溯的精髓,甚至作者本身都沒(méi)有想清楚自己用了回溯。

我這里提供的代碼把整個(gè)回溯過(guò)程充分的提現(xiàn)出來(lái),希望可以幫助大家看的明明白白!

本文:

https://github.com/youngyangyang04/leetcode-master?github.com

已經(jīng)收錄,里面還有l(wèi)eetcode刷題攻略、各個(gè)類型經(jīng)典題目刷題順序、思維導(dǎo)圖,可以fork到自己倉(cāng)庫(kù),有空看一看一定會(huì)有所收獲,如果對(duì)你有幫助也給一個(gè)star支持一下吧! 我的B站(里面有我講解的算法視頻已經(jīng)編程相關(guān)知識(shí)):

嗶哩嗶哩 ( ゜- ゜)つロ 乾杯~ Bilibili?space.bilibili.com

我是程序員Carl,哈工大師兄,先后在騰訊和百度從事技術(shù)研發(fā)多年,利用工作之余重刷leetcode,更多精彩算法文章盡在:代碼隨想錄,關(guān)注后,回復(fù)「Java」「C++」「python」「簡(jiǎn)歷模板」等等,有我整理多年的學(xué)習(xí)資料,可以加我微信,備注「?jìng)€(gè)人簡(jiǎn)介」+「組隊(duì)刷題」,拉你進(jìn)入刷題群,每天一道經(jīng)典題目分析,我選的每一道題目都不是孤立的,而是由淺入深一脈相承的,如果跟住節(jié)奏每篇連續(xù)著看,定會(huì)融會(huì)貫通。

總結(jié)

以上是生活随笔為你收集整理的消除左递归c++代码_「leetcode」129. 求根到叶子节点数字之和【递归中隐藏着回溯】详解...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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