在问 · 算法题解

110. 平衡二叉树

简单二叉树自底向上递归力扣原题 ↗

题目描述

输入二叉树的根节点 root,判断它是否为高度平衡的二叉树。

高度平衡的意思是:树中任何一个节点,其左子树与右子树的高度之差的绝对值都不超过 1。

是则返回 true,否则返回 false。空树视为平衡。树用层序数组表示,null 代表空位。

示例 1
输入:root = [3,9,20,null,null,15,7]
输出:true

解释:根的左子树高 1、右子树高 2,其余节点也都满足条件。

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

解释:根的左子树高 3,右子树高 1,相差 2。

示例 3
输入:root = []
输出:true

解释:空树是平衡的。

数据范围

  • 节点总数在 [0, 5000] 之间。
  • -10^4 <= Node.val <= 10^4

解题思路:自底向上递归

自底向上计算高度。height(node) 后序遍历:先求左子树高度,再求右子树高度,然后检查差值。一旦发现某棵子树不平衡,就返回 -1 作为标记,上层看到 -1 直接继续返回 -1,不再做多余计算。这样每个节点只访问一次。

为什么正确

height(node) 返回非负数时,这棵子树已经平衡且该数就是高度;返回 -1 表示子树内某处不平衡。

复杂度分析

时间 O(n),空间 O(h),h 为树高(递归栈)。

易错点

只比较根节点左右子树的高度是不够的,每个节点都要满足。另外自顶向下对每个节点重新算高度会变成 O(n^2)。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        def height(node):
            if not node:
                return 0
            lh = height(node.left)
            if lh == -1:
                return -1
            rh = height(node.right)
            if rh == -1 or abs(lh - rh) > 1:
                return -1
            return max(lh, rh) + 1
        return height(root) != -1

载入编辑器,自己跑一遍 →

其他解法

自顶向下按定义逐层检查,高度反复计算;自底向上在求高度的同时判断平衡,用 -1 提前剪枝,每个节点只访问一次。

解法 2:自顶向下递归 时间 O(n²),空间 O(h)

先写一个普通的 height 函数求子树高度。对当前节点,检查左右子树高度差不超过 1,再递归判断左子树和右子树都平衡。

直接照着定义写,容易想到。同一个节点的高度会被重复计算,最坏 O(n²);平衡树上是 O(n log n)。

class Solution:
    def isBalanced(self, root):
        def height(node):
            if not node:
                return 0
            return max(height(node.left), height(node.right)) + 1
        if not root:
            return True
        return (abs(height(root.left) - height(root.right)) <= 1
                and self.isBalanced(root.left) and self.isBalanced(root.right))

二叉树 专题的其他题目

查看 二叉树 全部题目 →