You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二叉树递归如何填充子树值?LeetCode 110题求解疑惑

理解LeetCode 110. 平衡二叉树的递归逻辑

我正在解决LeetCode的110. Balanced Binary Tree问题,对递归过程中子树值的填充方式感到困惑。参考若干解决方案后,得到了如下JavaScript代码:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    return treeHeight(root) !== -1;
};

function treeHeight(root){
    if(!root) return 0;
    const leftSubTree = treeHeight(root.left);
    const rightSubTree = treeHeight(root.right);
    if(leftSubTree === -1 || rightSubTree === -1) return -1; // how can recursion lead to either subtree being -1? At this point I don't know how this can be true other than "that's just how recursion works"
    if(Math.abs(leftSubTree - rightSubTree) > 1) return -1; // how are the values of either subtree even obtained here?
    return Math.max(leftSubTree, rightSubTree) + 1; // same as the previous question. how do either subtree even get values?
}

我试图理解以下代码行:

if(leftSubTree === -1 || rightSubTree === -1) return -1; // how can recursion lead to either subtree being -1? At this point I don't know how this can be true other than "that's just how recursion works"
    if(Math.abs(leftSubTree - rightSubTree) > 1) return -1; // how are the values of either subtree even obtained here?
    return Math.max(leftSubTree, rightSubTree) + 1; // same as the previous question. how do either subtree even get values?

我明白递归会遍历树的左侧和右侧,但不清楚递归是如何计算出子树值的,能否有人对此进行解释?


递归逻辑详解

这个treeHeight函数的核心是同时完成两个任务:计算子树的高度,以及判断子树是否平衡。它用返回-1表示当前子树不平衡,返回非负整数表示子树的实际高度。

1. 递归的终止条件

当root为null(空节点)时,返回0——空树的高度定义为0,这是递归的“终点”,所有子树的高度计算都会从这里开始回溯。

2. 深度优先的递归遍历

对于任意非空节点,函数会先递归计算左子树的高度leftSubTree,再递归计算右子树的高度rightSubTree。这个过程是深度优先的:比如会先一路挖到最左侧的叶子节点,再逐步向上回溯,依次计算每个节点的子树高度。

3. 为什么会返回-1?

  • 第一个判断if(leftSubTree === -1 || rightSubTree === -1) return -1:如果左/右子树已经返回-1,说明这个子树本身已经是不平衡的。既然子树不平衡,那么当前节点所在的整棵树肯定也不平衡,直接向上返回-1,不用再做后续计算,这是一种提前终止的优化。
  • 第二个判断if(Math.abs(leftSubTree - rightSubTree) > 1) return -1:如果左右子树的高度差超过1,说明当前节点的子树不符合平衡二叉树的要求,返回-1标记不平衡。

4. 子树高度的计算

如果以上两个判断都不触发,说明当前子树是平衡的,那么它的高度就是左右子树高度的最大值 + 1——加1是因为当前节点本身要算一层高度。

举个实际例子理解

假设我们有一棵平衡二叉树:

3
   / \
  9  20
    /  \
   15   7

递归执行过程:

  1. 计算节点9的左右子树:都是空节点,返回0。高度差为0,所以节点9的高度是max(0,0)+1=1。
  2. 计算节点15和7的左右子树:都是空节点,各自返回1。
  3. 计算节点20的左子树(15,返回1)和右子树(7,返回1),高度差0,所以节点20的高度是max(1,1)+1=2。
  4. 计算根节点3的左子树(9,返回1)和右子树(20,返回2),高度差1,所以根节点的高度是max(1,2)+1=3。最终treeHeight返回3,不是-1,所以isBalanced返回true。

再看一棵不平衡的树:

1
      / \
     2   2
    / \
   3   3
  / \
 4   4

递归执行过程:

  1. 节点4的左右子树都是空,返回1;节点3的左右子树都是4(返回1),返回2;节点2的左子树(3,返回2)和右子树(3,返回1),高度差1,返回3。
  2. 右侧的节点2左右子树都是空,返回1。
  3. 根节点1的左子树(2,返回3)和右子树(2,返回1),高度差2>1,返回-1。最终isBalanced返回false。

内容的提问来源于stack exchange,提问作者Bmoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:10:28