「leetcode」111.二叉樹的最小深度
111.二叉樹的最小深度
給定一個二叉樹,找出其最小深度。
最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。
說明: 葉子節點是指沒有子節點的節點。
示例:
給定二叉樹 [3,9,20,null,null,15,7],
返回它的最小深度 2.
思路
看完了這篇二叉樹:看看這些樹的最大深度,再來看看如何求最小深度。
直覺上好像和求最大深度差不多,其實還是差不少的。
遍歷順序上依然是後序遍歷(因為要比較遞迴返回之後的結果),但在處理中間節點的邏輯上,最大深度很容易理解,最小深度可有一個誤區,如圖:
這就重新審題了,題目中說的是:「最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。」,注意是「葉子節點」。
什麼是葉子節點,左右孩子都為空的節點才是葉子節點!
遞迴法
來來來,一起遞迴三部曲:
- 確定遞迴函式的引數和返回值
引數為要傳入的二叉樹根節點,返回的是int型別的深度。
程式碼如下:
int getDepth(TreeNode* node)
- 確定終止條件
終止條件也是遇到空節點返回0,表示當前節點的高度為0。
程式碼如下:
if (node == NULL) return 0;
- 確定單層遞迴的邏輯
這塊和求最大深度可就不一樣了,一些同學可能會寫如下程式碼:
int leftDepth = getDepth(node->left);
int rightDepth = getDepth(node->right);
int result = 1 + min(leftDepth, rightDepth);
return result;
這個程式碼就犯了此圖中的誤區:
如果這麼求的話,沒有左孩子的分支會算為最短深度。
所以,如果左子樹為空,右子樹不為空,說明最小深度是 1 + 右子樹的深度。
反之,右子樹為空,左子樹不為空,最小深度是 1 + 左子樹的深度。最後如果左右子樹都不為空,返回左右子樹深度最小值 + 1 。
程式碼如下:
int leftDepth = getDepth(node->left); // 左
int rightDepth = getDepth(node->right); // 右
// 中
// 當一個左子樹為空,右不為空,這時並不是最低點
if (node->left == NULL && node->right != NULL) {
return 1 + rightDepth;
}
// 當一個右子樹為空,左不為空,這時並不是最低點
if (node->left != NULL && node->right == NULL) {
return 1 + leftDepth;
}
int result = 1 + min(leftDepth, rightDepth);
return result;
遍歷的順序為後序(左右中),可以看出:「求二叉樹的最小深度和求二叉樹的最大深度的差別主要在於處理左右孩子不為空的邏輯。」
整體遞迴程式碼如下:
class Solution {
public:
int getDepth(TreeNode* node) {
if (node == NULL) return 0;
int leftDepth = getDepth(node->left); // 左
int rightDepth = getDepth(node->right); // 右
// 中
// 當一個左子樹為空,右不為空,這時並不是最低點
if (node->left == NULL && node->right != NULL) {
return 1 + rightDepth;
}
// 當一個右子樹為空,左不為空,這時並不是最低點
if (node->left != NULL && node->right == NULL) {
return 1 + leftDepth;
}
int result = 1 + min(leftDepth, rightDepth);
return result;
}
int minDepth(TreeNode* root) {
return getDepth(root);
}
};
精簡之後程式碼如下:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) return 0;
if (root->left == NULL && root->right != NULL) {
return 1 + minDepth(root->right);
}
if (root->left != NULL && root->right == NULL) {
return 1 + minDepth(root->left);
}
return 1 + min(minDepth(root->left), minDepth(root->right));
}
};
「精簡之後的程式碼根本看不出是哪種遍歷方式,所以依然還要強調一波:如果對二叉樹的操作還不熟練,儘量不要直接照著精簡程式碼來學。」
迭代法
相對於二叉樹:看看這些樹的最大深度,本題還可以使用層序遍歷的方式來解決,思路是一樣的。
如果對層序遍歷還不清楚的話,可以看這篇:二叉樹:層序遍歷登場!
「需要注意的是,只有當左右孩子都為空的時候,才說明遍歷的最低點了。如果其中一個孩子為空則不是最低點」
程式碼如下:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == NULL) return 0;
int depth = 0;
queue<TreeNode*> que;
que.push(root);
while(!que.empty()) {
int size = que.size();
depth++; // 記錄最小深度
int flag = 0;
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
if (!node->left && !node->right) { // 當左右孩子都為空的時候,說明是最低點的一層了,退出
flag = 1;
break;
}
}
if (flag == 1) break;
}
return depth;
}
};
本文:https://github.com/youngyangyang04/leetcode-master已經收錄,裡面還有leetcode刷題攻略、各個型別經典題目刷題順序、思維導圖,可以fork到自己倉庫,有空看一看一定會有所收穫,如果對你有幫助也給一個star支援一下吧!
我的B站(裡面有我講解的演算法視訊以及程式設計相關知識):https://space.bilibili.com/525438321
我是程式設計師Carl,哈工大師兄,先後在騰訊和百度從事技術研發多年,利用工作之餘重刷leetcode,更多 精彩演算法文章盡在: 程式碼隨想錄,關注後,回覆「Java」「C++」「python」「簡歷模板」等等,有我整理多年的學習資料,可以加我 微信,備註「個人簡介」+「組隊刷題」,拉你進入刷題群(無任何廣告,純個人分享),每天一道經典題目分析,我選的每一道題目都不是孤立的,而是由淺入深一脈相承的,如果跟住節奏每篇連續著看,定會融會貫通。
相關文章
- 111. 二叉樹的最小深度二叉樹
- 111. 二叉樹的最小深度(***)二叉樹
- leetcode 111 二叉樹的最小深度LeetCode二叉樹
- 二叉樹的最大深度和最小深度二叉樹
- 二叉樹的最大/最小深度二叉樹
- Day16 | 104.二叉樹的最大深度 、111.二叉樹的最小深度 、222.完全二叉樹的節點個數二叉樹
- 二叉樹的最小深度問題二叉樹
- 程式碼隨想錄演算法訓練營day16 | leetcode 104. 二叉樹的最大深度、559. N 叉樹的最大深度、111. 二叉樹的最小深度、222. 完全二叉樹的節點個數演算法LeetCode二叉樹
- 程式碼隨想錄 第十六天 | ● 104.二叉樹的最大深度 559.n叉樹的最大深度 ● 111.二叉樹的最小深度 ● 222.完全二叉樹的節點個數二叉樹
- 【leetcode 簡單】第二十七題 二叉樹的最小深度LeetCode二叉樹
- 程式碼隨想錄演算法訓練營第第16天 | 104.二叉樹的最大深度 、111.二叉樹的最小深度、222.完全二叉樹的節點個數演算法二叉樹
- 程式碼隨想錄演算法訓練營第十六天 | 104.二叉樹的最大深度 111.二叉樹的最小深度 222.二叉樹的節點個數演算法二叉樹
- 二叉樹的最小高度,最大高度(深度)和寬度二叉樹
- 程式碼隨想錄演算法訓練營第十四天| 226.翻轉二叉樹 、101. 對稱二叉樹、104.二叉樹的最大深度 (優先掌握遞迴)、111.二叉樹的最小深度演算法二叉樹遞迴
- LeetCode 104.二叉樹的最大深度LeetCode二叉樹
- 程式碼隨想錄演算法訓練營第十四天|leetcode226. 翻轉二叉樹、leetcode101.對稱二叉樹、leetcode104.二叉樹的最大深度、leetcode111.二叉樹的最小深度演算法LeetCode二叉樹
- 二叉樹的深度二叉樹
- 二叉樹深度二叉樹
- 二叉樹---深度二叉樹
- 程式碼隨想錄day14 || 226 翻轉二叉樹,101 對稱二叉樹, 104 二叉樹的最大深度, 111 二叉樹的最小深度二叉樹
- [Golang]力扣Leetcode—初級演算法—樹—二叉樹的最大深度Golang力扣LeetCode演算法二叉樹
- LeetCode每日一題:二叉樹的最大深度(No.104)LeetCode每日一題二叉樹
- 二叉樹的子結構、深度以及重建二叉樹二叉樹
- JZ-038-二叉樹的深度二叉樹
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 二叉樹的深度、寬度遍歷及平衡樹二叉樹
- 【劍指offer】二叉樹深度二叉樹
- Python二叉樹的三種深度Python二叉樹
- 每日一練(27):二叉樹的深度二叉樹
- 5分鐘瞭解二叉樹之LeetCode裡的二叉樹二叉樹LeetCode
- LeetCode 對稱二叉樹LeetCode二叉樹
- 劍指Offer-40-二叉樹的深度二叉樹
- 劍指offer——二叉樹的深度C++二叉樹C++
- 《劍指offer》:[39]求解二叉樹的深度二叉樹
- Maximum Depth of Binary Tree 二叉樹的深度二叉樹
- Leedcode-二叉搜尋樹的最小絕對差
- leetcode 530. Minimum Absolute Difference in BST二叉搜尋樹的最小絕對差 (簡單)LeetCode
- [每日一題] 第八題:二叉樹的深度每日一題二叉樹