力扣104.二叉树的最大深度 110. 平衡二叉树

104. 二叉树的最大深度(简单)

题目:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

示例

复制代码
给定二叉树 [3,9,20,null,null,15,7],
    3
   / \
  9  20
    /  \
   15   7
返回深度 3。

解法一:递归(DFS)

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (!root) return 0;
        return 1 + max(maxDepth(root->left), maxDepth(root->right));
    }
};

解法二:迭代(BFS,层序遍历)

cpp 复制代码
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (!root) return 0;
        queue<TreeNode*> q;
        q.push(root);
        int depth = 0;
        while (!q.empty()) {
            int size = q.size();
            for (int i = 0; i < size; ++i) {
                TreeNode* node = q.front(); q.pop();
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            ++depth;
        }
        return depth;
    }
};

110. 平衡二叉树(简单)

题目:给定一个二叉树,判断它是否是平衡二叉树。

注释:平衡二叉树是指该树所有节点的左右子树高度相差不大于1

示例

复制代码
输入:root = [3,9,20,null,null,15,7]
输出:true

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

解法:自底向上递归(后序遍历)

cpp 复制代码
class Solution {
public:
    bool isBalanced(TreeNode* root) {
        return getHeight(root) != -1;
    }
private:
    int getHeight(TreeNode* node) {
        if (!node) return 0;
        int left = getHeight(node->left);
        if (left == -1) return -1;
        int right = getHeight(node->right);
        if (right == -1) return -1;
        if (abs(left - right) > 1) return -1;
        return 1 + max(left, right);
    }
};

复杂度:时间 O(n),空间 O(n)(递归栈)。

二叉树遍历详解

二叉树的遍历是指按照某种顺序访问树中的每个节点,确保每个节点被访问一次。常见的遍历方式有四种:前序遍历中序遍历后序遍历层序遍历


一、后序遍历(Post-order Traversal)

定义 :先访问左子树,再访问右子树,最后访问根节点。
顺序 :左 → 右 → 根
用途:常用于释放树节点、计算树的高度、求表达式树的值等需要先处理子节点再处理父节点的场景。

递归实现

cpp 复制代码
void postorder(TreeNode* root) {
    if (!root) return;
    postorder(root->left);
    postorder(root->right);
    cout << root->val << " ";  // 访问根节点
}

示例树

复制代码
    1
   / \
  2   3
 / \
4   5

后序遍历结果:4 5 2 3 1


二、其他遍历方式

1. 前序遍历(Pre-order Traversal)
  • 顺序:根 → 左 → 右
  • 用途:复制树、序列化、前缀表达式。
  • 结果 (同上树):1 2 4 5 3
cpp 复制代码
void preorder(TreeNode* root) {
    if (!root) return;
    cout << root->val << " ";
    preorder(root->left);
    preorder(root->right);
}
2. 中序遍历(In-order Traversal)
  • 顺序:左 → 根 → 右
  • 用途:二叉搜索树(BST)的中序遍历得到有序序列。
  • 结果 (同上树):4 2 5 1 3
cpp 复制代码
void inorder(TreeNode* root) {
    if (!root) return;
    inorder(root->left);
    cout << root->val << " ";
    inorder(root->right);
}
3. 层序遍历(Level-order Traversal)
  • 顺序:从上到下,从左到右逐层访问。
  • 用途:广度优先搜索(BFS)、求树的最小深度、打印树形结构。
  • 结果 (同上树):1 2 3 4 5
cpp 复制代码
void levelOrder(TreeNode* root) {
    if (!root) return;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        TreeNode* node = q.front(); q.pop();
        cout << node->val << " ";
        if (node->left) q.push(node->left);
        if (node->right) q.push(node->right);
    }
}

三、递归与迭代实现对比

  • 递归:代码简洁,但可能因树深度过大导致栈溢出(如退化为链表)。
  • 迭代:需手动模拟栈,但可避免递归深度限制,且更容易控制。

例如,前序遍历的迭代实现:

cpp 复制代码
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> res;
    stack<TreeNode*> stk;
    if (root) stk.push(root);
    while (!stk.empty()) {
        TreeNode* node = stk.top(); stk.pop();
        res.push_back(node->val);
        if (node->right) stk.push(node->right);
        if (node->left) stk.push(node->left);
    }
    return res;
}

四、总结

遍历方式 访问顺序 典型应用
前序遍历 根 → 左 → 右 复制树、序列化
中序遍历 左 → 根 → 右 BST 排序输出
后序遍历 左 → 右 → 根 计算高度、释放树
层序遍历 逐层从左到右 BFS、最短路径

理解这些遍历是解决二叉树问题的基础,例如:

  • LeetCode 104 二叉树的最大深度 可以用后序遍历或层序遍历。
  • LeetCode 110 平衡二叉树 使用后序遍历自底向上判断高度差。
相关推荐
_深海凉_2 小时前
LeetCode热题100-只出现一次的数字
算法·leetcode·职场和发展
nianniannnn2 小时前
力扣206.反转链表 92.反转链表II
算法·leetcode·链表
澈2072 小时前
哈希表实战:从原理到手写实现
算法·哈希算法
旖-旎3 小时前
哈希表(存在重复元素||)(4)
数据结构·c++·算法·leetcode·哈希算法·散列表
Run_Teenage3 小时前
Linux:认识信号,理解信号的产生和处理
linux·运维·算法
無限進步D3 小时前
蓝桥杯赛前刷题
c++·算法·蓝桥杯·竞赛
CoderCodingNo3 小时前
【GESP】C++二级真题 luogu-B4497, [GESP202603 二级] 数数
开发语言·c++·算法
磊 子3 小时前
八大排序之冒泡排序+选择排序
数据结构·算法·排序算法
_深海凉_3 小时前
LeetCode热题100-买卖股票的最佳时机
leetcode