給定一個二元樹,找出其最大深度。
二元樹的最大深度是從根節點到最遠葉節點的最長路徑上的節點數。
範例:
輸入: 二元樹 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
輸出: 3
這道題要求找到二元樹的最大深度,這個問題可以透過遞迴法或者深度優先搜尋(DFS)或者廣度優先搜尋(BFS)來解。
廣度優先搜尋 BFS 版本的話,就是每遍歷完一層的所有節點後,深度就加1。
/**
* 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 maxDepth(TreeNode* root) {
if (root == nullptr)
return 0;
queue<TreeNode*> q;
q.push(root);
int depth = 0;
// BFS
while (!q.empty()) {
int count = q.size(); // 當前這層的節點數量
// 處理當前這層的所有節點
for (int i = 0; i < count; i++) {
TreeNode* node = q.front();
q.pop();
if (node->left != nullptr) {
q.push(node->left);
}
if (node->right != nullptr) {
q.push(node->right);
}
}
depth++;
}
return depth;
}
};
深度優先搜尋 DFS 版本的話,就是將 node 以及所在的深度推入 stack,遍歷每個 node 時去檢查是不是要更新最大深度。
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) {
return 0;
}
stack<pair<TreeNode*, int>> stk;
stk.push({root, 1});
int maxDepth = 0;
while (!stk.empty()) {
auto [node, depth] = stk.top(); // 取得當前節點和深度
stk.pop();
// 更新最大深度
maxDepth = max(maxDepth, depth);
if (node->left != nullptr) {
stk.push({node->left, depth + 1});
}
if (node->right != nullptr) {
stk.push({node->right, depth + 1});
}
}
return maxDepth;
}
};
使用 DFS 後序方式,我們可以從樹的根節點開始,遞迴計算每個節點的左右子樹的深度,最終回傳最大的一個。
這邊的深度是由底層空節點 0 開始,由底層往上,逐層加回每一層的深度。
思路:
null
(也就是到達了葉節點的下一層),我們回傳深度為 0
。null
,則分別計算左子樹和右子樹的深度。1
(因為要計算當前節點本身的深度)。這樣,我們可以透過遞迴來解決這個問題,不斷地尋找每個節點的最大深度。
class Solution {
public:
int maxDepth(TreeNode* root) {
// 如果當前節點為 null,回傳 0
if (root == nullptr) {
return 0; // 空節點深度為 0
}
// 遞迴計算左右子樹的最大深度
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
// 當前節點的最大深度是左右子樹深度的最大值加上 1
return max(leftDepth, rightDepth) + 1;
}
};
參考:
#104. Maximum Depth of Binary Tree