【算法-LeetCode】110. 平衡二叉树(递归)

110. 平衡二叉树 - 力扣(LeetCode)

发布:2021年10月10日21:30:53

问题描述及示例

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例 1:
【算法-LeetCode】110. 平衡二叉树(递归)
输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:
【算法-LeetCode】110. 平衡二叉树(递归)
输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

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

提示
树中的节点数在范围 [0, 5000] 内
-104 <= Node.val <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/balanced-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解(Map)

第一时间想到的解决方案就是利用递归计算二叉树的左右子树的高度,然后根据其差值返回最终结果。

成功前的尝试

按照上面的思路,我写出了下面的程序:

/**
 * 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) {
  if(!root) {
    return true; 
  }
  return  Math.abs(getHeight(root.left) - getHeight(root.right)) > 1 ? false : true; 

  function getHeight(root) {
    if(!root) {
      return 0;
    }
    return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
  }
};


提交记录
执行结果:解答错误
通过测试用例:203 / 228
输入:[1,2,2,3,null,null,3,4,null,null,4]
输出:true
预期结果:false
时间:2021/10/10 21:35

提供的几个测试用例都通过了,然后我自信满满地提交了,结果……没有如期通过……最后一个测试用例如下:

【算法-LeetCode】110. 平衡二叉树(递归)

没有考虑到根节点的左右子树可能也为非平衡二叉树

我上面的程序中只考虑了根节点的左右子树的高度差,但是虽然上面的二叉树的根节点的左右子树的高度差小于2,但是以根节点的左子节点为根的二叉树的左右子树高度差却大于等于2。很明显,这不是一棵平衡二叉树,但是程序只做了一层判断,所以返回 true

也就是说,上面的程序只能确定根节点的左右子树的高度差满足不超过2的条件,但是却不能保证该二叉树为平衡二叉树。

递归解法

经过一番推敲。我觉得程序出错的原因在于没有对平衡二叉树的判断条件进行深度应用,所以导致了只能满足一部分用例。所以需要在计算二叉树高度的递归函数 getHeight() 中添加对当前二叉树是否为平衡二叉树的判断,再通过返回值的形式将判断结果返回给上一层递归。

而且要注意一个传递关系:如果某棵子树不是平衡二叉树,则该子树所在的子树必然也不是平衡二叉树。

所以就需要一个标志量来确定当前子树是否为平衡二叉树。我是通过返回 -1 来标识当前子树是否为平衡二叉树的。

所以 getHeight() 函数的返回值就有两种情况:如果是平衡二叉树,就返回其高度,如果不是的话就返回 -1,所以最后只要判断 getHeight() 函数的返回值是否为 -1 即可。

/**
 * 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 getHeight(root) === -1 ? false : true;

  function getHeight(root) {
    if(!root) {
      return 0;
    }
    let leftHeight = getHeight(root.left);
    if(leftHeight === -1) {
      return -1;
    }
    let rightHeight = getHeight(root.right);    
    if(rightHeight === -1) {
      return -1;
    }
    return Math.abs(leftHeight - rightHeight) > 1 ? -1 : Math.max(leftHeight, rightHeight) + 1;
  }
};


提交记录
执行结果:通过
通过测试用例:228 / 228
执行用时:84 ms, 在所有 JavaScript 提交中击败了67.39%的用户
内存消耗:42.3 MB, 在所有 JavaScript 提交中击败了35.63%的用户
时间:2021/10/10 23:05

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

更新:2021年10月10日23:10:42

参考:平衡二叉树 - 平衡二叉树 - 力扣(LeetCode)

【更新结束】

有关参考

更新:2021年10月10日23:55:23
参考:【微信公众号:代码随想录 2020-10-02】二叉树:我平衡么?

上一篇:出现Could not load dynamic library ‘cudart64_110.dll‘; dlerror: cudart64_110.dll not found解决办法


下一篇:第五周训练题解