代碼隨想錄訓練營第二十三天| 572.另一顆樹的子樹 104.二叉樹的最大深度 559.N叉樹的最大深度 111.二叉樹的最小深度

572.另一顆樹的子樹:

狀態:已做出

?思路:

這道題目當時第一時間不是想到利用100.相同的樹思路來解決,而是先想到了使用kmp,不過這個題目官方題解確實是有kmp解法的,我使用的暴力解法,kmp的大致思路是使用前序遍歷整個樹的節點,并且要把所有的空子樹都考慮進去,不然會出現前序相同樹的結構不同的情況,這些節點都放入一個char型數組中,空節點可以任意使用一個字符來表示,做到這一步后就完全是把題目轉變為了kmp問題,使用kmp來解決既可,暴力解法的思路:使用和100.相同的樹相似的做法,遍歷root的每個節點,把每個節點都看成一顆子樹,然后這個子樹和subRoot使用和100題相同的做法,查看兩個樹是否相同就能判斷出最后的結果了。總體來說暴力解法的時間復雜度是O(n*m),而kmp的時間復雜度優化到O(n+m),n和m分別是root和subRoot的節點樹。
代碼如下:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public://兩顆樹進行比較是否相同bool dfs(TreeNode* root,TreeNode* sub) {if(!root && !sub) return true;if(!root || !sub ||(root->val!=sub->val)) return false;//這里的if語句把三種不相等的情況都包含進去了bool a1=dfs(root->left,sub->left);bool a2=dfs(root->right,sub->right);return a1 && a2;//需要左右子樹都為真才說明這兩個樹相同}//這個函數是用來遍歷樹的每個節點的,讓每個子樹都和subRoot判斷bool Subreturn(TreeNode* left, TreeNode* right) {bool rusult=dfs(left,right);if(rusult) return true;if(left==nullptr) return false;bool a1=Subreturn(left->left,right);bool a2=Subreturn(left->right,right);return a1 || a2;//使用遞歸來遍歷所有root的節點,最后只要有一處子樹和sunRoot相同就符合題意}bool isSubtree(TreeNode* root, TreeNode* subRoot) {if(!root) return false;return Subreturn(root,subRoot);}
};

遇到的困難:

當時做這道題目一開始以為使用100題的思路是優解,所以沒想過暴解,就一直在想使用這個思路怎能去優化解決題目,但是發現一直出現問題,因為這道題要優化時間的話必須要考慮判斷出錯后怎么去回溯,這就讓我想到了kmp,隨后看完官方的解法后才知道這到題目使用判斷相同數的思路就是暴力解法,必須要每個節點都判斷才能得到正確答案,官方題解還給出了一種使用哈希樹的解法,聽著就你難,所以完全看思路。

收獲:

這道題目使用判斷是否是相同的數的方法就是暴力,通過練習熟悉一下這種解法,做法和之前的100題幾乎一樣,這道題目跟字符串求是否有相同子串的思想很像。

104.二叉樹的最大深度:

文檔講解:代碼隨想錄|104.二叉樹的最大深度

視頻講解:二叉樹的高度和深度有啥區別?究竟用什么遍歷順序?很多錄友搞不懂 | LeetCode:104.二叉樹的最大深度_嗶哩嗶哩_bilibili

狀態:已做出

思路:

這下題目之前我使用層序遍歷解決過,這次主要是使用前序和后續來解決這代題目。后序的思路:使用后續就是求根結點的最大高度,我的遞歸結束條件是節點為空時返回0,每次遞歸設置兩個變量,分別保存這個節點的左右子樹的層數有多少,最后去這兩者的最大值,最后返回最大值加一,按照這個遞歸思路打到根結點就能返回最大深度。前序思路:前序是求最深的葉子結點深度。和后序遞歸不同,遞歸代碼的參數我多設計了一個變量n,用來記錄此時的層級,在遞歸到節點為空后返回n結束遞歸,每層設置兩個變量來保存次節點的左右子樹的最大深度,然后去這兩個變量的最大值,直接返回最大值就可以了。

后序遍歷:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int dfs(TreeNode* root) {if(root==nullptr) {return 0;//這里返回零是為了從最深的地方開始不斷向上回溯來記錄高度}int sum1=dfs(root->left);int sum2=dfs(root->right);int n=max(sum1,sum2);//去最大值return ++n;//這里需要把此時的節點考慮進去,所以要加一}int maxDepth(TreeNode* root) {if(!root) return 0;return dfs(root);}
};

前序遍歷:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int dfs(TreeNode* root,int n) {if(root==nullptr) {return n;//返回n,因為這里空節點不考慮}int sum1=dfs(root->left,n+1);//每次都要讓參數加一,記錄層級int sum2=dfs(root->right,n+1);int num=max(sum1,sum2);return num;//這里之所以不加一是因為在遍歷后序節點的時候num就已經把加一操作包含進去了,比如如果只有根節點的話,最后不加一也返回深度為1}int maxDepth(TreeNode* root) {if(!root) return 0;return dfs(root,0);}
};

遇到的困難:

這道題目使用前后序來做比層序遍歷難一點,其中的難點就是難以控制遞歸的代碼,不好記錄層級,首先后序我使用遞歸返回0的方式是為了考慮最后節點為空的那一層,隨后使用兩個變量分別保存左右子樹的最大深度,就是沒一層每一層的遞歸來找到最后根結點的最大深度的,這個點就是是遞歸抽象的地方,需要由深到淺來思考,不然就會想錯,最后返回的最大值我多加了1是為了把這一層考慮進去,因為左右子節點的最大高度都求出了,最后要加上這一次的層級返回。前序遞歸結束返回n是因為我在每層都講n累加了,所以直接返回n就行了,下面的兩個變量的遞歸傳入n+1就是累加層級,最后和后序一樣返回最大值,這里不和后序一樣返回最大值加一是因為在左右子樹遞歸后判斷的最大值就已經把這一層級考慮進去了,所以直接返回。

收獲:

這道題目使用層序遍歷比遞歸方法要簡單,主要是層序好理解,遞歸還是有點抽象,這道題對加深遞歸理想有一定的幫助,相比前中后序的簡單遞歸,這道題目需要更加了解遞歸的規則才能合理分配出層級或者高度的改變。

559.N叉樹的最大深度 :

文檔講解:代碼隨想錄|104.二叉樹的最大深度

狀態:已做出?

思路:

這道題目和上一道求二叉樹最大深度一樣,我使用了前序后序和層序三種遍歷方式去實現了這道題目。這里后序實現最后結束遞歸是返回的1,因為這里二叉樹后序不一樣,二叉樹可以遞歸到空節點,但是N叉樹不能,所以這里返回后必須要把這一層考慮進去,所以返回放是1,隨后的操作二叉樹的就差不多了,就是要使用循環來一直遍歷一個節點的所有節點,每次循環記比較大小,保存這些節點的最大值,最后好和二叉樹思想一樣,返回最大值加一。前序則和二叉樹放最大深度求法沒太大的區別,直接改成循環遍歷所有直接點既可。層序遍歷相比于遞歸就簡單多了,層序遍歷所有節點,記錄每層層級最后返回就可以了。

后序遍歷:

/*
// Definition for a Node.
class Node {
public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;}
};
*/class Solution {
public:int dfs(Node* root) {if(!root->children.size()) return 1;//這里是返回1,因為最后是遇到葉子節點才結束遞歸,要算上葉子節點int ans=0;//這里和而二叉樹不同,需要循環遍歷所有子節點。其他和二叉樹的思路差不多for(int i=0;i<root->children.size();++i) {int sum=dfs(root->children[i]);ans=max(sum,ans);}return ans+1;//算上此節點層級}int maxDepth(Node* root) {if(!root) return 0;return dfs(root);}
};

前序遍歷:

/*
// Definition for a Node.
class Node {
public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;}
};
*/class Solution {
public:int dfs(Node* root,int n) {if(!root->children.size()) return n;//這里在遞歸參數就考慮到了加一的情況,所以直接返回nint ans=0;for(int i=0;i<root->children.size();++i) {int sum=dfs(root->children[i],n+1);ans=max(sum,ans);}return ans;}int maxDepth(Node* root) {if(!root) return 0;return dfs(root,1);}
};

層序遍歷:

/*
// Definition for a Node.
class Node {
public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;}
};
*/class Solution {
public:int maxDepth(Node* root) {if(!root) return 0;queue<Node*>qu;qu.push(root);int n=0;while(!qu.empty()) {int size=qu.size();++n;//每一層都要加上層級for(int i=0;i<size;++i) {Node* temp=qu.front();qu.pop();for(int j=0;j<temp->children.size();++j) {qu.push(temp->children[j]);}}}return n;}
};

遇到的困難:

這道題目難點就是N叉樹有多個節點,需要在遞歸和層序遍歷里面設置一個循環來遍歷所有結點,還有一點就是N叉樹因為不會遞歸到空節點,所以后序需要對代碼進行一點細節的改善。

收獲:

這道題目就是二叉樹的進階,和二叉樹的求法沒太大區別,練習能進一步理解二叉樹的代碼思路。

?111.二叉樹的最小深度:

文檔講解:代碼隨想錄|111.二叉樹的最小深度

視頻講解:看起來好像做過,一寫就錯! | LeetCode:111.二叉樹的最小深度_嗶哩嗶哩_bilibili

狀態:已做出

思路:

這道題目使用層序我之前做過,這次主要是使用前序和后序的遞歸來實現,這道題目我覺得使用遞歸實現起來比求最大深度還要麻煩一點,這里容易出錯的問題文檔中有明確說明,就是不明確處理葉子結點就會出現誤判,比如根結點的左子樹為空時,不管右子樹是否為空最后出現的最小深度都是1。這道題的具體要求是要我們求根結點到最淺層級的深度有多大,所以遞歸的結束條件我這里設置的是到葉子節點后結束遞歸,后序為了考慮這一層所以返回1,前序我這里在遞歸里設置了一個參數n來記錄層級,和二叉樹的思路有點點相似,每到一層就n+1。不管是后序還是前序都先設置兩個變量,并讓變量指向int最大值,因為每次都需要比較取最小值,而且每次遞歸都要判斷此節點做右子樹必須是非空才能進行遞歸,這樣是為了不出現考慮空節點層級的情況。
代碼如下:

后序遍歷:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int dfs(TreeNode* root) {if(!root->left && !root->right) return 1;int sum1=INT_MAX,sum2=INT_MAX;//這里先設置兩個變量為最大值,因為下面的遞歸困難會因為子節點為空而不會改變變量的值//這里是為了避免文檔所說的錯誤,所以設置了if語句if(root->left)sum1=dfs(root->left);if(root->right)sum2=dfs(root->right);return min(sum1,sum2)+1;}int minDepth(TreeNode* root) {if(!root) return 0;return dfs(root);}
};

前序遍歷:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int dfs(TreeNode* root,int n) {if(!root->left && !root->right) return n;//葉子節點就直接返回結束遞歸int sum1=INT_MAX,sum2=INT_MAX;if(root->left)sum1=dfs(root->left,n+1);if(root->right)sum2=dfs(root->right,n+1);return min(sum1,sum2);}int minDepth(TreeNode* root) {if(!root) return 0;return dfs(root,1);//這里設置為1是直接先把根節點考慮進去了}
};

遇到的困難:

使用層序遍歷求最小比求最大要簡單,沒想到使用遞歸卻相反,求最小反而細節處更多。

收獲:

以上這些題目主要都是使用遞歸去實現的,主要是提升對遞歸的掌握成程度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/80933.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80933.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/80933.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【RabbitMq C++】消息隊列組件

RabbitMq 消息隊列組件 1. RabbitMq介紹2. 安裝RabbitMQ3. 安裝 RabbitMQ 的 C客戶端庫4. AMQP-CPP 庫的簡單使用4.1 使用4.1.1 TCP 模式4.1.2 擴展模式 4.2 常用類與接口介紹4.2.1 Channel4.3.2 ev 5. RabbitMQ樣例編寫5.1 發布消息5.2 訂閱消息 1. RabbitMq介紹 RabbitMq - …

鴻蒙NEXT開發動畫案例8

1.創建空白項目 2.Page文件夾下面新建Spin.ets文件&#xff0c;代碼如下&#xff1a; /*** SpinKit動畫組件 (重構版)* author: CSDN-鴻蒙布道師* since: 2025/05/14*/interface AnimationGroup {indexes: number[];delay: number; }ComponentV2 export struct SpinEight {Re…

MySQL全局優化

目錄 1 硬件層面優化 1.1 CPU優化 1.2 內存優化 1.3 存儲優化 1.4 網絡優化 2 系統配置優化 2.1 操作系統配置 2.2 MySQL服務配置 3 庫表結構優化 4 SQL及索引優化 mysql可以從四個層面考慮優化&#xff0c;分別是 硬件系統配置庫表結構SQL及索引 從成本和優化效果來看&#xf…

vue和springboot交互數據,使用axios【跨域問題】

vue和springboot交互數據&#xff0c;使用axios【跨域問題】 提示&#xff1a;幫幫志會陸續更新非常多的IT技術知識&#xff0c;希望分享的內容對您有用。本章分享的是node.js和vue的使用。前后每一小節的內容是存在的有&#xff1a;學習and理解的關聯性。【幫幫志系列文章】&…

FFMPEG 與 mp4

1. FFmpeg 中的 start_time 與 time_base start_time 流的起始時間戳&#xff08;單位&#xff1a;time_base&#xff09;&#xff0c;表示第一幀的呈現時間&#xff08;Presentation Time&#xff09;。通常用于同步多個流&#xff08;如音頻和視頻&#xff09;。 time_base …

AI世界的崩塌:當人類思考枯竭引發數據生態鏈斷裂

AI世界的崩塌&#xff1a;當人類思考枯竭引發數據生態鏈斷裂 ——論過度依賴AI創作對技術進化的反噬 一、數據生態的惡性循環&#xff1a;AI的“自噬危機” 當前AI模型的訓練依賴于人類創造的原始數據——書籍、論文、藝術作品、社交媒體動態等。據統計&#xff0c;2025年全球…

C++【STL】(2)string

C【STL】string用法擴展 1. assign&#xff1a;為字符串賦新值 用于替換字符串內容&#xff0c;支持多種參數形式。 常用形式&#xff1a; // 用另一個字符串賦值 str.assign("Hello World");// 用另一個字符串的子串&#xff08;從第6個字符開始&#xff0c;取5…

樹莓派4基于Debian GNU/Linux 12 (Bookworm)開啟VNC,使用MobaXterm連接VNC出現黑屏/灰屏問題

1. 開啟樹莓派的VNC服務 啟用VNC服務&#xff1a;通過raspi-config開啟 # 1. 通過 raspi-config 工具開啟 sudo raspi-config選擇 Interface Options → VNC → Yes退出時會自動啟動服務 檢查服務狀態&#xff1a; sudo systemctl status vncserver-x11-serviced正常輸出應顯示…

MongoDB使用x.509證書認證

文章目錄 自定義證書生成CA證書生成服務器之間的證書生成集群證書生成用戶證書 MongoDB配置java使用x.509證書連接MongoDBMongoShell使用證書連接 8.0版本的mongodb開啟復制集&#xff0c;配置證書認證 自定義證書 生成CA證書 生成ca私鑰&#xff1a; openssl genrsa -out ca…

Python爬蟲實戰:研究js混淆加密

一、引言 在當今數字化時代,數據已成為推動各行業發展的核心驅動力。網絡爬蟲作為一種高效的數據采集工具,能夠從互聯網上自動獲取大量有價值的信息。然而,隨著互聯網技術的不斷發展,許多網站為了保護自身數據安全和知識產權,采用了 JavaScript 混淆加密技術來防止數據被…

Java項目層級介紹 java 層級 層次

java 層級 層次 實體層 控制器層 數據連接層 Service : 業務處理類 Repository &#xff1a;數據庫訪問類 Java項目層級介紹 https://blog.csdn.net/m0_67574906/article/details/145811846 在Java項目中&#xff0c;層級結構&#xff08;Layered Architecture&#xf…

網絡安全頂會——SP 2025 論文清單與摘要

1、"Check-Before-you-Solve": Verifiable Time-lock Puzzles 時間鎖謎題是一種密碼學原語&#xff0c;它向生成者保證該謎題無法在少于T個順序計算步驟內被破解。近年來&#xff0c;該技術已在公平合約簽署和密封投標拍賣等場景中得到廣泛應用。然而&#xff0c;求解…

《100天精通Python——基礎篇 2025 第18天:正則表達式入門實戰,解鎖字符串處理的魔法力量》

目錄 一、認識正則表達式二、正則表達式基本語法2.1 行界定符2.2 單詞定界符2.3 字符類2.4 選擇符2.5 范圍符2.6 排除符2.7 限定符2.8 任意字符2.9 轉義字符2.10 反斜杠2.11 小括號2.11.1 定義獨立單元2.11.2 分組 2.12 反向引用2.13 特殊構造2.14 匹配模式 三、re模塊3.1 comp…

思邁特軟件攜手天陽科技,打造ChatBI金融智能分析新標桿

5月10日&#xff0c;廣州思邁特軟件有限公司&#xff08;以下簡稱“思邁特軟件”&#xff09;與天陽宏業科技股份有限公司&#xff08;以下簡稱“天陽科技”&#xff09;在北京正式簽署戰略合作協議。思邁特軟件董事長吳華夫、CEO姚詩成&#xff0c;天陽科技董事長兼總裁歐陽建…

OPENSSL-1.1.1的使用及注意事項

下載鏈接&#xff1a; OpenSSL1.1.1一個廣泛使用的開源加密庫資源-CSDN文庫 OpenSSL 1.1.1 是一個廣泛使用的開源加密庫&#xff0c;以下是其使用方法及注意事項&#xff1a; 使用方法 安裝&#xff1a; Linux系統&#xff1a; 從源碼編譯安裝&#xff1a;訪問 OpenSSL 官網…

數據庫優化

一、慢 SQL 排查全流程 1. 開啟慢查詢日志&#xff1a;精準定位問題 SQL 慢查詢日志是定位性能問題的首要工具&#xff0c;通過記錄執行超時或未使用索引的 SQL&#xff0c;為優化提供依據。 配置步驟&#xff1a; ① 臨時啟用&#xff08;生效至服務重啟&#xff09; sql …

GO語言-導入自定義包

文章目錄 1. 項目目錄結構2. 創建自定義包3. 初始化模塊4. 導入自定義包5. 相對路徑導入 在Go語言中導入自定義包需要遵循一定的目錄結構和導入規則。以下是詳細指南&#xff08;包含兩種方式&#xff09;&#xff1a; 1. 項目目錄結構 方法1&#xff1a;適用于Go 1.11 &#…

記錄算法筆記(2025.5.11) 二叉樹的中序遍歷

給定一個二叉樹的根節點 root &#xff0c;返回 它的 中序 遍歷 。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,3,2] 示例 2&#xff1a; 輸入&#xff1a;root [] 輸出&#xff1a;[] 示例 3&#xff1a; 輸入&#xff1a;root [1] …

【iptables防火墻】 -- DDos防御

最近有客戶要定制路由器的默認防火墻等級&#xff0c;然后涉及到了DDos規則&#xff0c;對比客戶提供的規則發現我們現有的規則存在明顯的錯誤&#xff0c;在此記錄一下如何使用iptables防護DDoS攻擊 直接貼一下規則 #開啟TCP SYN Cookies 機制 sysctl -w net.ipv4.tcp_synco…

[Java][Leetcode simple]26. 刪除有序數組中的重復項

思路 第一個元素不動從第二個元素開始&#xff1a;只要跟上一個元素不一樣就放入數組中 public int removeDuplicates(int[] nums) {int cnt1;for(int i 1; i < nums.length; i) {if(nums[i] ! nums[i-1]) {nums[cnt] nums[i];}}return cnt;}