1、二叉树的最大深度
后序递归法:
class Solution {
public:
int getdepth(TreeNode* node) { //利用根节点的高度求二叉树的深度
if (node == nullptr) return 0; //叶子结点高度为1,那叶子结点的子节点(NULL)高度就为0
int leftdepth = getdepth(node->left); // 左
int rightdepth = getdepth(node->right); // 右
int depth = 1 + max(leftdepth, rightdepth); // 中
return depth;
}
int maxDepth(TreeNode* root) {
return getdepth(root);
}
};
精简后的:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
return 1 + max(maxDepth(root->left), maxDepth(root->right));
}
};
前序递归法:
class Solution { // 前序递归
public:
int result; // 两个函数共用一个变量
void getdepth(TreeNode* node, int depth) {
result = depth > result ? depth : result; // 中 持续更新result
if (node->left == nullptr && node->right == nullptr) //结束条件,即遇到叶子结点
return;
if (node->left) { // 左
depth++; // 深度+1
getdepth(node->left, depth);
depth--; // 回溯,深度-1 (这里为什么要回溯,是因为函数栈弹栈时node从子结点回溯到父结点,相应的深度也要减一)
}
if (node->right) { // 右
depth++; // 深度+1
getdepth(node->right, depth);
depth--; // 回溯,深度-1
}
}
int maxDepth(TreeNode* root) {
result = 0; //初始化为0
if (root == nullptr) return result;
getdepth(root, 1); //根节点存在的情况,深度最小为1
return result;
}
};
精简后的:
class Solution {
public:
int result;
void getdepth(TreeNode* node, int depth) {
result = depth > result ? depth : result; // 中
if (node->left == nullptr && node->right == nullptr) return;
if (node->left) { // 左
getdepth(node->left, depth + 1); //至于这里为什么没有减一,看下图
}
if (node->right) { // 右
getdepth(node->right, depth + 1);
}
}
int maxDepth(TreeNode* root) {
result = 0;
if (root == nullptr) return result;
getdepth(root, 1);
return result;
}
};
层序迭代法:
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
queue<TreeNode *> que;
que.push(root); // 将根节点入队
int depth = 0; // 当前深度初始化为0
while (!que.empty()) {
int size = que.size(); // 当前层的节点数
depth++; // 遍历到下一层,深度+1
// 遍历当前层的所有节点
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);
}
}
// 当队列为空时,说明已经遍历完所有节点,此时depth即为最大深度
return depth;
}
};
2、N叉树的最大深度
递归法:
class Solution {
public:
int maxDepth(Node* root) {
if (root == nullptr) return 0;
int depth = 0;
for (auto child: root->children) {
depth = max(depth, maxDepth(child));
}
return depth + 1;
}
};
迭代法:
class Solution {
public:
int maxDepth(Node* root) {
if (root == nullptr) return 0;
queue<Node *> que;
que.push(root); // 将根节点入队
int depth = 0; // 当前深度初始化为0
while (!que.empty()) {
int size = que.size(); // 当前层的节点数
depth++; // 遍历到下一层,深度+1
// 遍历当前层的所有节点
while(size--) {
Node* node = que.front(); // 取出队首节点
que.pop(); // 弹出队首节点
// 将当前节点的子节点入队
for (auto child: node->children) {
que.push(child);
}
}
}
// 当队列为空时,说明已经遍历完所有节点,此时depth即为最大深度
return depth;
}
};
3、二叉树的最小深度
后序递归:
class Solution {
public:
int getDepth(TreeNode* node) {
if (node == nullptr) return 0;
int leftDepth = getDepth(node->left); // 左
int rightDepth = getDepth(node->right); // 右
// 中
// 当一个左子树为空,右不为空,这时并不是最低点
if (node->left == nullptr && node->right != nullptr) {
return 1 + rightDepth;
}
// 当一个右子树为空,左不为空,这时并不是最低点
if (node->left != nullptr && node->right == nullptr) {
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 == 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->left), minDepth(root->right));
}
};
前序递归:
class Solution {
private:
int result;
void getdepth(TreeNode* node, int depth) {
// 函数递归终止条件
if (node == nullptr) return;
// 中,处理逻辑:判断是不是叶子结点
if (node->left == nullptr && node->right == nullptr) {
result = min(result, depth); //更新result值
}
if (node->left) { // 左
getdepth(node->left, depth + 1);
}
if (node->right) { // 右
getdepth(node->right, depth + 1);
}
}
public:
int minDepth(TreeNode* root) {
if (root == nullptr) return 0;
result = INT_MAX;
getdepth(root, 1);
return result;
}
};
层序迭代:
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == nullptr) return 0;
queue<TreeNode *> que;
que.push(root); // 将根节点入队
int depth = 0; // 当前深度初始化为0
while (!que.empty()) {
int size = que.size(); // 当前层的节点数
depth++; // 遍历到下一层,深度+1
// 遍历当前层的所有节点
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front(); // 取出队首节点
que.pop(); // 弹出队首节点
if (node->left == nullptr && node->right ==nullptr)
return depth;
// 将当前节点的子节点入队
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
// 当队列为空时,说明已经遍历完所有节点,此时depth即为最大深度
return depth;
}
};
4、完全二叉树的节点个数
后序递归:
class Solution {
private:
int getNodesNum(TreeNode* cur) {
if (cur == nullptr) return 0;
int leftNum = getNodesNum(cur->left); // 左
int rightNum = getNodesNum(cur->right); // 右
int treeNum = leftNum + rightNum + 1; // 中
return treeNum;
}
public:
int countNodes(TreeNode* root) {
return getNodesNum(root);
}
};
精简后
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
return 1 + countNodes(root->left) + countNodes(root->right);
}
};
层序迭代:
class Solution {
public:
int countNodes(TreeNode* root) {
queue<TreeNode*> que;
if (root != nullptr) que.push(root);
int result = 0;
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; ++i) {
TreeNode* node = que.front();
que.pop();
result++; // 记录节点数量
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
}
}
return result;
}
};
利用完全二叉树的性质的递归写法:
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; // 这里初始为0是有目的的,为了下面求指数方便
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
}
// 单层递归逻辑
int leftTreeNum = countNodes(root->left); // 左
int rightTreeNum = countNodes(root->right); // 右
int result = leftTreeNum + rightTreeNum + 1; // 中
return result;
//return countNodes(root->left) + countNodes(root->right) + 1; //上面四行可以精简成一行
}
};