二叉树结点高度:由下往上,该节点到根结点的最长简单路径边的条数或者结点数(取决0还是1开始计数)
二叉树结点深度:由上往下,根节点到该结点的最长简单路径边的条数或者结点数(取决0还是1开始计数)
根节点的高度即为二叉树的最大深度
心得
- 还是没想清楚往遍历上靠,还是向一层一层往下累加,最好还行基于不同递归考虑好对应需要处理的逻辑
题解
- 本题递归可以采用前序或者后序遍历,也可迭代法
- 后序遍历即从地往上算高度,+1到根节点即可,前序类似逻辑往下算深度
// 递归——后序
class Solution {
public:
int getDepth(TreeNode* root) {
if (root == nullptr) return 0;
int left = getDepth(root->left);
int right = getDepth(root->right);
return 1 + max(left, right);
}
int maxDepth(TreeNode* root) {
return getDepth(root);
}
};
// 简化版
class Solution {
public:
int maxDepth(TreeNode* root) {
return 1 + max(maxDepth(root->left),maxDepth(root->right));
}
};
// 递归——前序
// 迭代——层序
class Solution {
public:
int maxDepth(TreeNode* root) {
int depth = 0;
queue<TreeNode*> que;
if (root == nullptr) return depth;
que.push(root);
while (!que.empty()) {
depth += 1;
int size = que.size();
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);
}
}
return depth;
}
};
559. N 叉树的最大深度
类似上题逻辑
// 递归
class Solution {
public:
int maxDepth(Node* root) {
int depth = 0;
if (root == nullptr) return 0;
for (int i = 0; i < root->children.size(); i++) {
depth = max(depth, maxDepth(root->children[i]));
}
return 1 + depth;
}
};
// 迭代
class Solution {
public:
int maxDepth(Node* root) {
int depth = 0;
if (root == nullptr) return 0;
queue<Node*> que;
que.push(root);
while (!que.empty()) {
depth++;
int size = que.size();
while (size--) {
Node* node = que.front();
que.pop();
for (int i = 0; i < node->children.size(); i++) {
if (node->children[i]) que.push(node->children[i]);
}
}
}
return depth;
}
};
111. 二叉树的最小深度
心得
题解
- 可以后序遍历,层序遍历均可,最小深度定义,左右空树情况处理,即单层处理逻辑与最大深度大不相同
// 递归——后序
class Solution {
public:
int getDepth(TreeNode* root) {
if (root == nullptr) return 0;
int leftDepth = getDepth(root->left);
int rightDepth = getDepth(root->right);
if (root->left == nullptr && root->right != nullptr) return 1 + rightDepth;
if (root->left != nullptr && root->right == nullptr) return 1 + leftDepth;
return 1 + min(leftDepth, rightDepth);
}
int minDepth(TreeNode* root) {
return getDepth(root);
}
};
// 精简版
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == nullptr) return 0;
if (root->left == nullptr && root->right != nullptr) {
return 1 + minDepth(root->right);
}
if (root->left != nullptr && root->right == nullptr) {
return 1 + minDepth(root->left);
}
return 1 + min(minDepth(root->right), minDepth(root->left));
}
};
// 迭代法——层序遍历
class Solution {
public:
int minDepth(TreeNode* root) {
int depth = 0;
queue<TreeNode*> que;
if (root != nullptr) que.push(root);
while (!que.empty()) {
depth++;
int size = que.size();
while (size--) {
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) { // 当一层一层往下的时候,遇到第一个叶子结点即为最小深度
return depth;
}
}
}
return depth;
}
};
222. 完全二叉树的节点个数
心得
题解
- 完全二叉树的特点在于一定是由于若干满二叉树组成的,所以判断满二叉树直接用公式,非满二叉树用递归可减少计算复杂度由O(n)降到O(logn*logn)
- 对于满二叉树的判断,只要遍历最左侧深度和最右侧深度一致即未满二叉树
- 类似最大深度写法,后序遍历即可
// 获取普通二叉树个数——后序递归,时空O(n) O(logn)
class Solution {
public:
int getNodesNum(TreeNode* cur) {
if (cur == nullptr) return 0;
int leftNums = getNodesNum(cur->left);
int rightNums = getNodesNum(cur->right);
return leftNums + rightNums + 1;
}
int countNodes(TreeNode* root) {
return getNodesNum(root);
}
};
// 完全二叉树定义——后序遍历
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 实际深度1,但是为下面指数计算方便
while (left) { // 左子树深度
left = left->left;
leftDepth++;
}
while (right) {
right = right->right; // 求右子树深度
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1;
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};