这是我参与2022首次更文挑战的第31天,活动详情查看:2022首次更文挑战
题目描述
提供一个二叉树,需要你判断它是不是高度平衡的二叉树。是则返回true,否则返回false。
什么是高度平衡? 上一篇文章讲过,
就是任意节点的左右子树的层级之差的绝对值不超过 1。
如果根节点是空的(null),则返回true。
举个例子:(灵魂画手前来报到😀)
任意节点的左边树和右边树层级相差刚好为1,所以是平衡二叉树
根节点的左边树和右边树层级相差大于1,所以不是平衡二叉树
节点2的左边树的层级为2, 右边树的层级为0,相差超过1, 所以不是平衡二叉树
思路分析
第一种方法(递归)
这个方法其实是在上一篇文章二叉树的最大深度方法上改造的。
如果没有根节点的时候,直接返回true。
定义一个findLevel函数,寻找节点的左右边树的最大层级,从根节点开始遍历,使用try-catch包裹,
当一发现不是平衡二叉树时,直接throw error,这样可以中断后面的遍历。
遍历的过程中如果当前节点为null,则代表当前节点没有子节点,返回0
如果不为null,则递归去找当前节点的左右边树的层级,每次递归都加一,代表一层,最后取二者的最大值返回(使用Math.max方法),这个就是最大层级。
在返回之前,比较当前节点的左右边树的最大层级之差是否大于1,如果大于1,抛出error,中断遍历。
最终递归遍历结束后,如果没有中断,则代表时平衡二叉树,返回true即可。
/**
* 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 flag
try {
function findLevel (root) {
if (!root) return 0
const leftLevel = findLevel(root.left)
const rightLevel = findLevel(root.right)
if (Math.abs(leftLevel - rightLevel) > 1) {
throw new Error()
}
return Math.max(leftLevel, rightLevel) + 1
}
findLevel(root)
} catch (err) {
return false
}
return true
};
第二种方法(递归)
这个方法也是使用递归方法,跟第一种方法类似,先定义函数findLevel,找当前节点的最大层级
然后它是先判断根节点左右边树是否时为平衡二叉树。
如果是,则再递归遍历左边树的子节点以及右边树的子节点
只要有不符合平衡二叉树的,则返回false。
如果都符合的才返回true。
这个方法会对整个节点遍历两次,复杂度会比第一种方法高一倍。
/**
* 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
function findLevel (root) {
if (!root) return 0
return Math.max(findLevel(root.left), findLevel(root.right)) + 1
}
return Math.abs(findLevel(root.left) - findLevel(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right)
};