二叉树的最大深度
二叉树的高度有两种定义:
- 从根节点到最深节点的最长路径的节点数。
- 从根到最深节点的最长路径的边数。
我们这里采用第一种定义。
递归
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == NULL) return 0;
int m = maxDepth(root->left);
int n = maxDepth(root->right);
return (m > n) ? m + 1 : n + 1;
}
};
深搜
以叶节点的深度为准,每次遇到叶节点,看能否更新当前的最大深度。
栈中除了存储每个树节点的指针之外,还需要存储每个节点的深度。
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == NULL) return 0;
int result = 0;
stack<pair<TreeNode*, int>> s;
s.emplace(root, 1);
while(!s.empty()) {
TreeNode* temp = s.top().first;
int depth = s.top().second;
s.pop();
if(temp->left == NULL && temp->right == NULL) {
result = max(result, depth);
}
if(temp->left != NULL) {
s.emplace(temp->left, depth + 1);
}
if(temp->right != NULL) {
s.emplace(temp->right, depth + 1);
}
}
return result;
}
};
广搜
转化为广度优先搜索(层序遍历),也就是看有多少层。
- 创建空队列保存二叉树的每一层节点,初始化标识二叉树高度的变量
height
为0 - 一层一层地遍历二叉树,每向下遍历一层,高度
height
加 1 - 计算每一层的节点数量,当下一层的节点为 0 时,结束遍历
class Solution {
public:
int maxDepth(TreeNode *root) {
if(root == NULL) {
return 0;
}
int height = 0;
queue<TreeNode* > q;
q.push(root);
while(!q.empty()) {
height++;
int node_number = q.size();
while(node_number > 0) {
TreeNode* temp = q.front();
q.pop();
if(temp->left != NULL) {
q.push(temp->left);
}
if(temp->right != NULL) {
q.push(temp->right);
}
node_number--;
}
}
return height;
}
};
二叉树的最小深度
递归
class Solution {
public:
int minDepth(TreeNode* root) {
if(root == NULL) return 0;
int m = minDepth(root->left);
int n = minDepth(root->right);
return (m == 0 || n == 0) ? (m + n + 1) : min(m, n) + 1;
}
};
深搜
使用栈,栈中除了存储每个树节点之外,还需要存储每个树节点所在层数的信息。
遇到叶节点,看是否能更新目前的最小深度,知道所有的节点访问完成。
class Solution {
public:
int minDepth(TreeNode* root) {
if(root == NULL) return 0;
int result = INT_MAX;
stack<pair<TreeNode*, int>> s;
s.emplace(root, 1);
while(!s.empty()) {
TreeNode* temp = s.top().first;
int depth = s.top().second;
s.pop();
if(depth > result) { // 剪枝
continue;
}
if(temp->left == NULL && temp->right == NULL) { // 遇到了叶节点,看能否更新最小深度
result = min(result, depth);
}
if(temp->left != NULL) {
s.emplace(temp->left, depth + 1);
}
if(temp->right != NULL) {
s.emplace(temp->right, depth + 1);
}
}
return result;
}
};
广搜
使用队列,下面列了两种实现方法:
- 第一种,队列中存储每个树节点及其深度,找到最上层的叶节点,将其深度返回即可。
- 第二种,队列中仅存储树节点,深度只用一个全局变量来记录。每次只搜索树的一层,用一个变量
node_number
来记录当前层是否搜索完成。
因为是层序遍历的,所以遇到的第一个叶节点,其所在的层数肯定是该树的最小深度。
class Solution {
public:
int minDepth(TreeNode *root) {
if (root == nullptr) {
return 0;
}
queue<pair<TreeNode *, int> > que;
que.emplace(root, 1);
while (!que.empty()) {
TreeNode *node = que.front().first;
int depth = que.front().second;
que.pop();
if (node->left == nullptr && node->right == nullptr) {
return depth;
}
if (node->left != nullptr) {
que.emplace(node->left, depth + 1);
}
if (node->right != nullptr) {
que.emplace(node->right, depth + 1);
}
}
return 0;
}
};
class Solution {
public:
int minDepth(TreeNode *root) {
if(root == NULL) {
return 0;
}
int height = 0;
queue<TreeNode* > q;
q.push(root);
while(!q.empty()) {
height++;
int node_number = q.size();
while(node_number > 0) {
TreeNode* temp = q.front();
q.pop();
if(temp->left == NULL && temp->right == NULL) {
return height;
}
if(temp->left != NULL) {
q.push(temp->left);
}
if(temp->right != NULL) {
q.push(temp->right);
}
node_number--;
}
}
return height;
}
};