代碼隨想錄二刷 | 二叉樹 | 110.平衡二叉樹

代碼隨想錄二刷 | 二叉樹 | 110.平衡二叉樹

  • 題目描述
  • 解題思路
    • 遞歸
    • 迭代
  • 代碼實現
    • 遞歸法
    • 迭代法

題目描述

110.平衡二叉樹

給定一個二叉樹,判斷它是否是高度平衡的二叉樹。

本題中,一棵高度平衡二叉樹定義為:

一個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過 1 。

示例 1:
在這里插入圖片描述
輸入:root = [3,9,20,null,null,15,7]
輸出:true

示例 2:
在這里插入圖片描述
輸入:root = [1,2,2,3,3,null,null,4,4]
輸出:false

示例 3:

輸入:root = []
輸出:true

提示:

  • 樹中的節點數在范圍 [0, 5000] 內
  • -104 <= Node.val <= 104

解題思路

二叉樹節點的高度:從根節點到該節點的最長簡單路徑邊的條數

二叉樹節點的深度:從該節點到葉子節點的最長簡單路徑變的條數

在這里插入圖片描述
求深度可以從上到下去查詢,所以需要前序遍歷,而求高度只能從下到上去查,只能后序遍歷。

因此本題使用后序遍歷。

遞歸

遞歸三部曲

  1. 確定遞歸函數的參數和返回值
    參數:當前傳入的節點
    返回值:因為求的是高度,所以為int

    如果當前傳入節點為根節點的二叉樹已經不是二叉平衡樹了,還返回高度的話就沒有意義了。

    所以如果已經不是二叉平衡樹了,可以返回 -1 來標記已經不符合平衡樹的規則了。

    int getHeight(TreeNode* node)
    
  2. 確定終止條件
    遇到空節點時終止,返回0,表示當前節點為根節點的樹高度為 0

    if (node == NULL) {return 0;
    }
    
  3. 確定單層遞歸的邏輯
    分別求出左右子樹的高度,如果差值小于等于 1 ,則返回當前二叉樹的高度,否則返回 -1,表示已經不是平衡二叉樹了。

    int leftHeight = getHeight(node->left);
    if (leftHeight == -1) return -1;
    int rightHeight = getHeight(ndoe->right);
    if (rightHeight == -1) return -1;
    int result;
    if (abs(leftHeight - rightHeight) > 1) {result = -1;	
    } else {result = 1 + max(leftHeight, rightHeight);
    }
    return result;
    

迭代

本題的迭代方式可以先定義一個函數,專門用來求高度。

這個函數通過棧模擬的后序遍歷找每一個節點的高度(其實是通過求傳入節點為根節點的最大深度來求的高度)

// cur節點的最大深度,就是cur的高度
int getDepth(TreeNode* cur) {stack<TreeNode*> st;if (cur != NULL) st.push(cur);int depth = 0; int result = 0;while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop();st.push(node);st.push(NULL);depth++;if (node->right) st.push(node->right);if (node->left) st.push(node->left);} else {st.pop();node = st.top();st.pop();depth--;}result = result > depth ? result : depth;}return result;
}

然后再用棧來模擬后序遍歷,遍歷每一個節點的時候,再去判斷左右孩子的高度是否符合,代碼如下:

bool isBalanced(TreeNode* root) {stack<TreeNode*> st;if (root == NULL) return true;st.push(root);while (!st.empty()) {TreeNode* node = st.top();st.pop();if (abs(getDepth(node->left) - getDepth(node->right)) > 1) {return fasle;}if (node->right) st.push(node->right);if (node->left) st.push(node->left);}return true;
}

當然此題用迭代法,其實效率很低,因為沒有很好的模擬回溯的過程,所以迭代法有很多重復的計算。

雖然理論上所有的遞歸都可以用迭代來實現,但是有的場景難度可能比較大。

例如:都知道回溯法其實就是遞歸,但是很少人用迭代的方式去實現回溯算法!

因為對于回溯算法已經是非常復雜的遞歸了,如果再用迭代的話,就是自己給自己找麻煩,效率也并不一定高。

代碼實現

遞歸法

class Solution {
public:int getHeight(TreeNode* node) {if (node == NULL) return 0;int leftHeight = getHeight(node->left);if (leftHeight == -1) return -1;int rightHeight = getHeight(node->right);if (rightHeight == -1) return -1;return abs(leftHeight - rightHeight) > 1 ? -1 : 1 + max(leftheight, rightHeight);}bool isBalanced(TreeNode* root) {return getHeight(root) == -1 ? false : true;}
};

迭代法

class Solution {
public:
class Solution {
private:int getDepth(TreeNode* cur) {stack<TreeNode*> st;if (cur != NULL) st.push(cur);int depth = 0; // 記錄深度int result = 0;while (!st.empty()) {TreeNode* node = st.top();if (node != NULL) {st.pop();st.push(node);                          // 中st.push(NULL);depth++;if (node->right) st.push(node->right);  // 右if (node->left) st.push(node->left);    // 左} else {st.pop();node = st.top();st.pop();depth--;}result = result > depth ? result : depth;}return result;}public:bool isBalanced(TreeNode* root) {stack<TreeNode*> st;if (root == NULL) return true;st.push(root);while (!st.empty()) {TreeNode* node = st.top(); st.pop();if (abs(getDepth(node->left) - getDepth(node->right)) > 1) {return false;}if (node->right) st.push(node->right);           // 右(空節點不入棧)if (node->left) st.push(node->left);             // 左(空節點不入棧)}return true;}
};

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

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

相關文章

EMNLP 2023 獲獎論文公布,大模型、NLP等領域火爆

EMNLP是計算語言學和自然語言處理領域頂級國際會議之一&#xff0c;屬于CCF B類&#xff0c;是由 ACL 下屬的SIGDAT小組主辦的NLP領域頂級國際會議&#xff0c;一年舉辦一次。相較于ACL&#xff0c;EMNLP更偏向于NLP在各個領域解決方案的學術探討。 今年的EMNLP 2023 已于2023…

table表格table/tr/td寬度和高度的設置

關于html中table表格tr,td的?度和寬度 做?頁的時候經常會遇到各種各樣的問題&#xff0c;經常遇到的?個就是會碰到表格被內容撐開的問題。 設置table樣式為 table-layout: fixed; 寬度可以了&#xff0c;但是高度會被撐高。怎么設置都不行&#xff0c;只能給這個td標簽單獨…

【Linux】 線程池

線程池 什么是線程池&#xff1f; 一次預先申請一批線程&#xff0c;讓這批線程有任務&#xff0c;就處理任務&#xff1b;沒任務&#xff0c;就處于等待狀態。 為什么要有線程池&#xff1f; 以空間換時間&#xff0c;預先申請一批線程&#xff0c;當有任務到來&#xff0c;可…

將rtsp視頻流發送到AWS Kinesis Video Streams的方案——使用Gstreamer(C++) Command Line

大綱 1 創建Kinesis Video Streams1.1 創建視頻流1.2 記錄Creation Time 2 創建策略2.1 賦予權限2.2 限制資源2.3 Json格式描述&#xff08;或上面手工設置&#xff09;2.4 注意事項 3 創建IAM用戶3.1 生成密鑰對3.2 附加策略3.3 記錄訪問密鑰對 4 編譯C 創建者庫5 發送6 檢查參…

JavaScript <關于逆向RSA非對稱加密算法的案例(代碼剖析篇)>--案例(五點一)

引用上文: CSDNhttps://mp.csdn.net/mp_blog/creation/editor/134857857 剖析: var bitsPerDigit16; // 每個數組元素可以表示的二進制位數// 數組復制函數&#xff0c;將源數組部分復制到目標數組的指定位置 function arrayCopy(src, srcStart, dest, destStart, n) {var m…

國內地址地區智能解析,無需完整地址也能正確匹配

頁面直接引入使用 已打包成單文件dist/bundle.js 可以直接通過標簽引用 <script src="./bundle.js"></script> <script>var results = AddressParse.parse(福建省福州市福清市石竹街道義明綜合樓3F,15000000000,asseek);console.log(results);…

OD機考真題搜集:服務失效判斷

題目 某系統中有眾多服務,每個服務用字符串(只包含字母和數字,長度<=10)唯一標識,服務間可能有依賴關系,如A依賴B,則當B故障時導致A也故障。 依賴具有傳遞性,如A依賴B,B依賴C,當C故障時導致B故障,也導致A故障。 給出所有依賴關系,以及當前已知故障服務,要求輸…

git提交代碼報錯Git: husky > pre-commit

目錄 git提交代碼報錯原因解決方法&#xff08;三種&#xff09;1、第一種2、第二種3、第三種 git提交代碼報錯原因 這個問題是因為當你在終端輸入git commit -m “XXX”,提交代碼的時候,pre-commit(客戶端)鉤子&#xff0c;它會在Git鍵入提交信息前運行做代碼風格檢查。如果代…

Kotlin 中密封類、枚舉類與密封接口的對比分析

在 Kotlin 編程語言中&#xff0c;密封類&#xff08;Sealed Classes&#xff09;、枚舉類&#xff08;Enum Classes&#xff09;和密封接口&#xff08;Sealed Interfaces&#xff09;是處理一組固定類型的強大工具。它們在 Kotlin 中扮演著特殊的角色&#xff0c;特別是在創建…

【小白專用】MySQL創建數據庫和創建數據表

1.在Windows開始搜索輸入Mysql,并選擇第一個打開。 2.輸入安裝時的密碼 3.說明安裝成功。 二、創建數據庫 1. 連接 MySQL 輸入 mysql -u root -p 命令&#xff0c;回車&#xff0c;然后輸入 MySQL 的密碼(不要忘記了密碼)&#xff0c;再回車&#xff0c;就連接上 MySQL 了。 …

數據庫常用鎖

數據庫鎖是一種用于管理并發訪問的機制&#xff0c;以確保數據的一致性和完整性。在并發訪問的情況下&#xff0c;多個事務可能同時嘗試訪問相同的數據&#xff0c;而數據庫鎖能夠協調這些訪問&#xff0c;防止數據不一致的問題。以下是一些常見的數據庫鎖及其詳細解釋&#xf…

C語言-統計素數并求和

本題要求統計給定整數M和N區間內素數的個數并對它們求和。 輸入格式: 輸入在一行中給出兩個正整數M和N&#xff08;1≤M≤N≤500&#xff09;。 輸出格式: 在一行中順序輸出M和N區間內素數的個數以及它們的和&#xff0c;數字間以空格分隔。 輸入樣例: 10 31輸出樣例: 7…

深入Redis過程-持久化

目錄 redis實現持久化 RDB 觸發機制-定期方法 定期-手動觸發 save bgsave 定期-自動觸發 AOF 開啟AOF功能 刷新緩沖區策略 重寫機制 混合持久化 Redis事務 事務相關的命令 MULTI EXEC DISCARD WATCH redis實現持久化 RDB RDB叫做Redis數據備份文件&#xf…

強大的公式編輯器 —— MathType最新版本安裝與使用

強大的公式編輯器 —— MathType最新版本安裝與使用 由于使用了很長時間的機械硬盤出現壞道&#xff0c;安裝在其中的MathType6.9&#xff08;精簡版&#xff09;也沒辦法使用了&#xff0c;本來想安裝個高版本的MathType&#xff0c;比如MathType7.4&#xff0c;但在網上苦苦…

如何更改Jupyter Notebook中的環境?

1.首先&#xff0c;打開終端 2.接著&#xff0c;分別輸入以下命令 conda env list 把EXPose替換為自己的環境變量 conda activate EXPose 3.接下來安裝‘ ipykernel ’軟件包 conda install ipykernel 4. 將該環境添加到Jupyter Notebook中&#xff1b;在Jupyter Notebook…

HTB Surveillance

Surveillance 2023年12月10日 12:13:35User nmap Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-10 12:15 CST Stats: 0:00:37 elapsed; 0 hosts completed (1 up), 1 undergoing Connect Scan Connect Scan Timing: About 59.83% done

小白第一次開私服怎么吸引玩家

大家好&#xff0c;我是咕嚕-凱撒&#xff0c;在現在這個網絡社會很多人為了放松一下會選擇打打游戲&#xff0c;私服也就成為了許多玩家為了尋找新鮮體驗的熱門選擇&#xff0c;很多小白就發現了這個契機但是吸引玩家加入自己的服務器也就成了一個比較頭疼的問題&#xff0c;下…

Wrong number of values of control parameter 2(Halcon 錯誤代碼:1402)

threshold (ImageReduced1, Region, 0,min2(75,Min)) 程序運行到這一句&#xff0c;出現錯誤 原因是其中的參數Min為空數組 解決方案&#xff1a;判斷了下可以輸出Min的區域是否存在&#xff0c;不存在跳過這一步。

八叉樹bt文件轉為grid文件的代碼及編譯流程

目的 點云文件轉為八叉樹文件 代碼 在一個文件夾中新建兩個文件&#xff0c;pcd2bt.cpp和CMakeLists.txt&#xff0c;分別寫入&#xff1a; grid3d_node.cpp #include <ros/ros.h> #include <string> #include "grid3d.hpp"int main(int argc, char…

【Maven技術專題】「實戰開發系列」盤點Maven項目中打包需要注意到的那點事兒

Maven項目打包需要注意到的那點事兒 Maven是什么Maven打包插件的作用Maven打包后經常出現的問題maven構建可運行Jar包 Maven打包的三種方式Maven打包的最簡單的方法maven-jar-pluginMANIFEST.MF文件部分MANIFEST.MF的文件內容jar包的拷貝機制在pom.xml中配置 maven-jar-plugin的…