首页 > 试题广场 >

判断是不是平衡二叉树

[编程题]判断是不是平衡二叉树
  • 热度指数:544407 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
输入一棵节点数为 n 二叉树,判断该二叉树是否是平衡二叉树。
在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树
平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
样例解释:
样例二叉树如图,为一颗平衡二叉树
注:我们约定空树是平衡二叉树。

数据范围:,树上节点的val值满足
要求:空间复杂度,时间复杂度

输入描述:
输入一棵二叉树的根节点


输出描述:
输出一个布尔类型的值
示例1

输入

{1,2,3,4,5,6,7}

输出

true
示例2

输入

{}

输出

true

说明:本题目包含复杂数据结构TreeNode,点此查看相关信息
采用双递归:
IsBalanced_Solution用于遍历所有节点,对所有节点进行平衡二叉树判断。函数deep用于计算节点的深度。
function IsBalanced_Solution(pRoot)
{
    // write code here
    if(pRoot == null){
        return true
    }
    let bool1 = IsBalanced_Solution(pRoot.left)
    let bool2 = IsBalanced_Solution(pRoot.right)
    if(!(bool1 && bool2)){
        return false
    }

    return Math.abs(deep(pRoot.left) - deep(pRoot.right)) < 2
}

function deep(pRoot) {
    if(pRoot == null){
        return 0
    }
    return Math.max(deep(pRoot.left), deep(pRoot.right)) + 1
}

发表于 2022-09-06 16:19:45 回复(0)
function IsBalanced_Solution(pRoot)
{
    // write code here
    let flag=true
    if(!pRoot)return true
    function height(root){
        if(!root) return  0
        let l=height(root.left)
        let r=height(root.right)
        if(l-r>1||r-l>1) flag=false//这里最好还是用外部标记
        return Math.max(l+1,r+1)
    }
    height(pRoot)
   if(flag==false) return false
    return true
}

发表于 2022-08-02 15:16:31 回复(0)
function IsBalanced_Solution(pRoot)
{
    // write code here
    if(pRoot==null) return true;
    //获取一个节点的树高
    function getTreeHight(node){
        if(node==null) return 0;
        let left = getTreeHight(node.left);
        let right = getTreeHight(node.right);
        return (left>right?left:right)+1;
    }
    //遍历二叉树
    let left = getTreeHight(pRoot.left)
	let right = getTreeHight(pRoot.right)
	if(Math.abs(left - right) > 1) return false
	return IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right)

}

发表于 2022-03-08 15:15:53 回复(0)
function IsBalanced_Solution(pRoot)
{
    // write code here
    return balanced(pRoot) !== -1
}
function balanced(root) {
    if(!root) {
        return 0
    }
    let left = balanced(root.left)
    let right = balanced(root.right)
    if(left === -1 || right === -1 || Math.abs(left-right) > 1) {
        return -1
    }
    return Math.max(left,right) + 1
}
发表于 2021-11-24 15:14:12 回复(0)
自底向上后序遍历
function IsBalanced_Solution(pRoot)
{
    // write code here
    if(!pRoot) {
        return true
    }
    function dfs(pRoot) {
        if(!pRoot) return 0
        let l = dfs(pRoot.left)
        let r = dfs(pRoot.right)
        if(l == -1 || r==-1 || Math.abs(l-r)>1) {
            return -1
        }
        return Math.max(l, r)+1
    }
    return dfs(pRoot) !== -1
}
module.exports = {
    IsBalanced_Solution : IsBalanced_Solution
};


发表于 2021-10-02 17:00:22 回复(0)
function IsBalanced_Solution(pRoot)
{
    if (!pRoot) return true;
    return Math.abs(getMaxDepth(pRoot.left) - getMaxDepth(pRoot.right)) < 2;
}
function getMaxDepth(root) {
    if (!root) return 0;
    return Math.max(getMaxDepth(root.left), getMaxDepth(root.right)) + 1;
}

编辑于 2021-04-19 17:38:21 回复(0)
function Depth(pRoot){
    if(!pRoot){
        return 0;
    }
    var left = Depth(pRoot.left);
    if(left == -1){
        return -1;
    }
    var right = Depth(pRoot.right);
    if(right == -1){
        return -1;
    }
    if(Math.abs(left - right) > 1){
        return -1;
    }
    return Math.max(left,right) + 1;
}
function IsBalanced_Solution(pRoot)
{
    // write code here
    return Depth(pRoot) != -1;
    
}

发表于 2021-03-27 11:21:00 回复(0)
深度优先遍历 平衡二叉树是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
function IsBalanced_Solution(pRoot)
{
    // write code here
      if(pRoot == null) return true;
      function dfs(root) {
          if(root == null) return 0;
          return Math.max(dfs(root.left), dfs(root.right)) + 1;
      }
    let l = dfs(pRoot.left);
    let r = dfs(pRoot.right);
    return Math.abs(l - r) <= 1 && IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
}

编辑于 2021-07-08 11:24:59 回复(0)
/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */

/**
 * 我的解题思路:
 * 1.直接复用上道题的逻辑,即先获取左右子树的深度,然后看它们差的绝对值是否小于等于1
 *
 * @param {*} pRoot
 */
function IsBalanced_Solution(pRoot)
{
    // write code here
    const fn = root => root ? Math.max(1 + fn(root.left), 1 + fn(root.right)) : 0;
    return pRoot ? Math.abs(fn(pRoot.left) - fn(pRoot.right)) <= 1 : true;
}

/**
 * 评论区TOP的解题思路:
 * 1.看起来跟我的思路好像差不多,实际上在对左右子树递归判断时处理不一样
 * 2.该思路是在发现某个子树不是平衡二叉树时,就直接原路返回到根节点并给出结果
 * 3.而我的思路是每次都会遍历完所有的子树
 *
 * @param {*} pRoot
 */
function topIsBalanced_Solution(pRoot)
{
    // write code here
    const fn = root => {
        if (!root) {
            return 0;
        }
        const left = fn(root.left);
        if (left === -1) {
            return -1;
        }
        const right = fn(root.right);
        if (right === -1) {
            return -1;
        }
        return Math.abs(left - right) > 1 ? -1 : 1 + Max(left, right);
    };
    return fn(pRoot) !== -1;
}

发表于 2020-06-18 00:13:43 回复(0)
JavaScript解法:递归判断是否平衡二叉树、递归求深度
function IsBalanced_Solution(pRoot)
{
    if(pRoot == null){
        return true;
    }
    return Math.abs(maxDepth(pRoot.left) - maxDepth(pRoot.right)) <= 1&&
        IsBalanced_Solution(pRoot.left)&&IsBalanced_Solution(pRoot.right)
}
function maxDepth(root){
    if(root == null){
        return 0;
    }
    return 1+Math.max(maxDepth(root.left),maxDepth(root.right));
}


发表于 2019-08-28 11:13:23 回复(0)
function TreeNode(x) {
    return {
        val:x,
        left:null,
        right:null
    }
}


function IsBalanced_Solution(pRoot)
{
    function TreeDepth(pRoot)
    {
        // write code here
        if(!pRoot) {
            return 0
        }
        const l = TreeDepth(pRoot.left)
        const r = TreeDepth(pRoot.right)
        const max = l > r ? l : r
        return max + 1
    }


    if(!pRoot) {
        return true
    }
    const l_d = TreeDepth(pRoot.left)
    const r_d = TreeDepth(pRoot.right)
    const dis = Math.abs(l_d-r_d)
    return dis <= 1 && IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right)
}

编辑于 2019-08-24 00:33:41 回复(0)
// 每个子树的深度之差不超过1
// 方法1.求二叉树所有子树的深度,需要两层递归,分别求两个树的深度会重复遍历二叉树,时间复杂度高。
// 方法2.后续遍历二叉树,
// 在遍历二叉树每个节点前都会遍历其左右子树
// 比较左右子树的深度,差值<=1返回true
// 左右字数有一个不是平衡的,或差值>1返回false
// js没有引用传递,所以当有一颗树不平衡时返回-1,其余返回树的深度


    function IsBalanced_Solution(pRoot) {
      return isBalanced(pRoot) != -1;
    }

    function isBalanced(node) {
      if (!node) {
        return 0;
      }
      const left = isBalanced(node.left);
      const right = isBalanced(node.right);
      if (left != -1 && right != -1) {
        const diff = left - right;
        if (diff <= 1 && diff >= -1) {
          return Math.max(left, right) + 1;
        }
      }
      return -1;
    }

发表于 2019-02-28 00:36:59 回复(0)
function IsBalanced_Solution(pRoot)
{
    // write code here
    var res = findDeepAndIsBalanced(pRoot);
    function findDeepAndIsBalanced(node) {
        if (!node) return { isBalanced: true, depth: 0 };
        var leftRes = findDeepAndIsBalanced(node.left);
        var rightRes = findDeepAndIsBalanced(node.right);
        var isBalanced = Math.abs(leftRes.depth - rightRes.depth) <= 1;
        return { isBalanced, depth: Math.max( leftRes.depth, rightRes.depth ) + 1};
    }
    return res.isBalanced
}

子节点只需要遍历一次

发表于 2018-08-04 18:47:18 回复(0)
在上一题的基础上,先得到该树的左右子树的深度,然后判断深度差是否小于等于1,若是,则判断其左右子树是否为平衡树。

/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */
function IsBalanced_Solution(pRoot)
{
    // write code here
    //pRoot为空节点,则为平衡树,返回true
    if(pRoot == null){
        return true;
    }
    var leftDep = treeDep(pRoot.left);
    var rightDep = treeDep(pRoot.right);
    //leftDep和rightDep的差为0/1,则该树为平衡树,那么继续判断其左右/子树是否为平衡树。只有但子树也为平衡数时,才返回true
    if(Math.abs(leftDep-rightDep) <= 1){
        return IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
    }
    else{return false;}
}
function treeDep(pRoot){
    if(pRoot == null){
        return 0;
    }
    var leftDep = treeDep(pRoot.left);
    var rightDep = treeDep(pRoot.right);
    return 1+(leftDep>rightDep?leftDep:rightDep);
}

发表于 2018-05-29 17:08:44 回复(0)
平衡二叉树是满足以下条件的二叉树:要么是一棵空树,要么左右子树都是平衡二叉树,并且左右子树的深度之差的绝对值不大于1.由此可知。要判断一棵树是不是平衡二叉树,只要判断它的左右子树的深度之差。问题又到了如何求一棵树的深度上去了。
function IsBalanced_Solution(pRoot)
{
    // write code here
    if(pRoot==null)return true;
    return Math.abs(depth(pRoot.left)-depth(pRoot.right))<=1;
}
function depth(root){
    if(!root)return 0;
    var left = 1+depth(root.left);
    var right = 1+depth(root.right);
    return Math.max(left,right);
}

发表于 2018-04-25 14:37:23 回复(0)
JS来啦来来啦啦啦啦
正常思路,应该会获得节点的左子树和右子树的高度,然后比较高度差是否小于1。也就是这样
function IsBalanced_Solution(pRoot)
{
    if(pRoot==null) return true;
    let leftLen=TreeDepth(pRoot.left);
    let rightLen=TreeDepth(pRoot.right);
    return Math.abs(rightLen-leftLen)<=1&&IsBalanced_Solution(pRoot.left)&&IsBalanced_Solution(pRoot.right);

}
function TreeDepth(pRoot){
    if(pRoot==null) return 0;
    let leftLen=TreeDepth(pRoot.left);
    let rightLen=TreeDepth(pRoot.right);
    return Math.max(leftLen,rightLen)+1;
}
可是这样有一个问题,就是节点重复遍历了,影响效率了。
改进办法就是在求高度的同时判断是否平衡,如果不平衡就返回-1,否则返回树的高度。
并且当左子树高度为-1时,就没必要去求右子树的高度了,可以直接一路返回到最上层了。
function IsBalanced_Solution(pRoot)
{
    return TreeDepth(pRoot)!=-1;
}
function TreeDepth(pRoot){
    if(pRoot==null) return 0;
    let leftLen=TreeDepth(pRoot.left);
    if(leftLen==-1)
        return -1;
    let rightLen=TreeDepth(pRoot.right);
    if(rightLen==-1)
        return -1;
    return Math.abs(leftLen-rightLen)>1?-1:Math.max(leftLen,rightLen)+1;
}

编辑于 2018-04-10 04:39:51 回复(0)
js代码
function IsBalanced_Solution(pRoot)
{
    if (!pRoot) return true;
    return depth(pRoot.left)-depth(pRoot.right)>=-1 && depth(pRoot.left)-depth(pRoot.right)<=1;
}

function depth(pRoot) {
    
    if(!pRoot)
        return 0;
    return 1 + (depth(pRoot.left)>depth(pRoot.right) ? depth(pRoot.left) : depth(pRoot.right));
}
发表于 2017-08-18 09:40:18 回复(0)