110. 平衡二叉树 - 力扣(LeetCode)
发布:2021年10月10日21:30:53
问题描述及示例
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:true
示例 2:
输入: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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的题解(递归)
其实这题和我之前做的【LeetCode-236. 二叉树的最近公共祖先】的思路有点类似,两者都是要对每一层递归的结果做处理:
第一时间想到的解决方案就是利用递归计算二叉树的左右子树的高度,然后根据其差值返回最终结果。
成功前的尝试
按照上面的思路,我写出了下面的程序:
/**
* 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
提供的几个测试用例都通过了,然后我自信满满地提交了,结果……没有如期通过……最后一个测试用例如下:
我上面的程序中只考虑了根节点的左右子树的高度差,但是虽然上面的二叉树的根节点的左右子树的高度差小于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) {
// 由于递归的结果会一层层往上传递,所以如果发现根节点的高度返回值为-1,
// 则说明当前二叉树不是平衡二叉树
return getHeight(root) === -1 ? false : true;
// getHeight 用于获取以 root 为根节点的二叉树的高度
function getHeight(root) {
// 如果当前节点为空,则直接返回 0 作为高度,这也是递归的终止条件
if(!root) {
return 0;
}
// 计算当前节点的左子树高度
let leftHeight = getHeight(root.left);
if(leftHeight === -1) {
// 如果当前节点的左子树的高度为 -1,说明当前节点的左子树不为平衡二叉树,
// 此时应该停止往下递归,直接返回 -1
return -1;
}
// 计算当前节点的右子树高度
let rightHeight = getHeight(root.right);
if(rightHeight === -1) {
// 这和上面同理
return -1;
}
// 如果左右子树都是平衡二叉树,则判断左右子树的高度差是否大于1
// 如果大于1,则说明则说明以当前节点为根节点的二叉树不是平衡二叉树,此时返回-1
// 否则的话,返回当前子树的高度(当前子树的高度即为左右子树中较高者的高度加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
【更新结束】
有关参考
更新:2021年10月10日23:55:23
参考:【微信公众号:代码随想录 2020-10-02】二叉树:我平衡么?
更新:2021年10月11日10:59:28
参考:【算法-LeetCode】236. 二叉树的最近公共祖先(递归;回溯)_赖念安的博客-CSDN博客