首页 > 试题广场 >

判断是不是平衡二叉树

[编程题]判断是不是平衡二叉树
  • 热度指数:544019 时间限制: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,点此查看相关信息
class Solution {
public:
    int getDepth(TreeNode* t){
        if(t==NULL)
            return 0;
        int leftDepth=getDepth(t->left);
        int rightDepth=getDepth(t->right);
        return leftDepth>rightDepth?leftDepth+1:rightDepth+1;
    }
    bool IsBalanced_Solution(TreeNode* pRoot) {
		if(pRoot==NULL)
            return true;
        int leftDepth=getDepth(pRoot->left);
        int rightDepth=getDepth(pRoot->right);
        int diffDepth=leftDepth-rightDepth;
        if(diffDepth<-1 || diffDepth>1){
            return false;
        }else{
            return (IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right));
        }
    }
};

发表于 2016-03-18 17:31:18 回复(1)
class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {
         if(!pRoot)
               return true;
         if(!pRoot->left&&!pRoot->right)
               return true;
         int l = getDepth(pRoot->left);
         int r = getDepth(pRoot->right);
         if(l-r>1||l-r<-1)
             return false;
        return IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right);
        
    }
    int getDepth(TreeNode *pRoot)
    {
        if(!pRoot)
              return 0;
        if(!pRoot->left&&!pRoot->right)
              return 1;
        int l = getDepth(pRoot->left);
        int r = getDepth(pRoot->right);
        
        return l>r?l+1:r+1;
    }
};

发表于 2017-09-02 19:44:52 回复(0)
class Solution {
public:
   int TreeDepth(TreeNode* pRoot)
{
if(pRoot==NULL) return 0;
return max(1+TreeDepth(pRoot->left),1+TreeDepth(pRoot->right));
}
bool IsBalanced_Solution(TreeNode* pRoot)
{
if(pRoot==NULL) return true;
if(abs(TreeDepth(pRoot->left)-TreeDepth(pRoot->right))>1)
return false;
return IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right);
}
};
发表于 2016-01-27 10:40:18 回复(1)
最直接的做法,遍历每个结点,借助一个获取树深度的递归函数,根据该结点的左右子树高度差判断是否平衡,然后递归地对左右子树进行判断。
public classSolution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) {
            return true;
        }
        return Math.abs(maxDepth(root.left) - maxDepth(root.right)) <= 1 &&
            IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
     
    private int maxDepth(TreeNode root) {
        if(root == null) {
            return 0;
        }
        return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
    }
}
这种做法有很明显的问题,在判断上层结点的时候,会多次重复遍历下层结点,增加了不必要的开销。如果改为从下往上遍历,如果子树是平衡二叉树,则返回子树的高度;如果发现子树不是平衡二叉树,则直接停止遍历,这样至多只对每个结点访问一次。
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        return getDepth(root) != -1;
    }
    
    private int getDepth(TreeNode root) {
        if (root == null) return 0;
        int left = getDepth(root.left);
        if (left == -1) return -1;
        int right = getDepth(root.right);
        if (right == -1) return -1;
        return Math.abs(left - right) > 1 ? -1 : 1 + Math.max(left, right);
    }
}

编辑于 2018-04-12 20:13:40 回复(82)
#include <stdbool.h>

int dfs(struct TreeNode* root, bool* ans) {
  if (!root) return 0;
  const int lh = dfs(root->left,  ans); // lh == left subtree height
  const int rh = dfs(root->right, ans); // rh == right subtree height
  if (abs(lh - rh) > 1) *ans = false;
  return 1 + fmax(lh, rh);
}

bool IsBalanced_Solution(struct TreeNode* pRoot ) {
  if (!pRoot) return true;
  bool ans = true;
  dfs(pRoot, &ans);
  return ans;
}

发表于 2021-07-29 08:13:58 回复(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)
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
            if (root == null) {
            return true;
        }
        if(Math.abs(getDeep(root.left, 0) - getDeep(root.right, 0)) > 1) {
            return false;
        }
        IsBalanced_Solution(root.right);
        IsBalanced_Solution(root.left);
        return true;
    }    
    public int getDeep(TreeNode node, int count) {
        if (node == null) {
            return count;
        }
        return Math.max(getDeep(node.left, count + 1), getDeep(node.right, count + 1));
    }
}


发表于 2018-09-03 09:51:29 回复(0)

import java.util.Stack;
import java.util.ArrayList;

public class Solution {
    public boolean res = true;
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null) {
            return true;
        }
        TreeNode cur = root;
        bs(cur);
        return res;
        //return Math.abs(bs(cur.left) - bs(cur.right)) <= 1 ? true : false;
    }
    
    public int bs(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int left = bs(node.left);
        int right = bs(node.right);
        if (Math.abs(left - right) > 1) {
            res = false;
        }
        return right > left ? right + 1 : left + 1;
    }
}

发表于 2018-07-13 23:55:18 回复(0)
class Solution:
    def IsBalanced_Solution(self, pRoot):
        return self.solution(pRoot)
    
    def getDepth(self,tree):
        if tree is None: return 0
        if not (tree.left or tree.right):return 1
        return 1 + max(self.getDepth(tree.left),self.getDepth(tree.right))

    def solution(self,tree):
        if tree is None:return True
        
        left = self.getDepth(tree.left)
        right = self.getDepth(tree.right)
        if abs(left-right) > 1:return False
        
        return  self.solution(tree.left) and  self.solution(tree.right)

编辑于 2018-04-09 16:49:20 回复(1)
//后序遍历,因为根是最后遍历到的,所以前面的数据已经有了
class Solution {
public:
    bool m_flag=true;
    bool IsBalanced_Solution(TreeNode* pRoot) {
		vis(pRoot);
        return m_flag;
    }
    
    int vis(TreeNode *p){
         if(!p)return 0;
         int l=vis(p->left);
         int r=vis(p->right);
         if(l-r>1 || r-l>1)m_flag=false;        
         return max(1+l,1+r);
    }
};

发表于 2017-08-20 20:56:57 回复(0)
class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {
	    try{
            height(pRoot);
            return true;
        }catch(string * e){
            return false;
        }
    }
    
    int height(TreeNode * root){
        if(!root)return 0;
		int left = 1 + height(root->left);
        int right = 1 + height(root->right);
		if(abs(left - right)>1)throw new string();
        return max(left,right);
    }
};

编辑于 2017-05-07 14:35:34 回复(1)
    int balance(TreeNode* root){
        if(!root)
            return 0;
        int left=balance(root->left);  //左子树高度  
        if(left==-1)     //如果左子树返回-1,说明左子树不平衡,返回-1提前终止
            return -1;
        int right=balance(root->right);  //右子树高度 
        if(right==-1)  //如果右子树返回-1,说明右子树不平衡,返回-1提前终止
            return -1;
        if(left-right>1 || left-right<-1)  //左右子树高度差超过1,返回-1表示不平衡
            return -1;
        return max(left,right)+1;  //执行到这一步说明左右子树平衡,返回子树高度
    }
    bool IsBalanced_Solution(TreeNode* pRoot) {
        return balance(pRoot) != -1;
    }

编辑于 2016-05-03 11:05:54 回复(0)
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
    int getTreeDepth(TreeNode* pRoot){
        if(pRoot==NULL)
            return 0;
        int leftDepth=getTreeDepth(pRoot->left);
        int rightDepth=getTreeDepth(pRoot->right);
        int depth=max(leftDepth,rightDepth)+1;
        return depth;
    }
    
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot==NULL)
            return true;
        int left=getTreeDepth(pRoot->left);
        int right=getTreeDepth(pRoot->right);
        if(abs(left-right)>1)
            return false;
        return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);
}
};
发表于 2015-04-10 09:32:32 回复(0)
public class Solution {
    //判断根节点左右子树的深度,高度差超过1,则不平衡
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root==null) {
			return true;
		}
		int left = getTreeDepth(root.left);
		int right = getTreeDepth(root.right);
		return Math.abs(left-right)>1?false:true;
    }
    //求取节点的深度
	public static int getTreeDepth(TreeNode root) {
		if (root==null) {
			return 0;
		}
		int leftDepth = 1+getTreeDepth(root.left);
		int rightDepth = 1+getTreeDepth(root.right);
		return leftDepth>rightDepth?leftDepth:rightDepth;
	}
}

发表于 2016-09-04 11:39:24 回复(5)
递归的方法
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root==null)
            return true;
      
        int left=depth(root.left);
        int right=depth(root.right);
        if(Math.abs(left-right)>1)
            return false;
        
        boolean booleft=IsBalanced_Solution(root.left);
        boolean booright=IsBalanced_Solution(root.right);
        return booleft&&booright;
    }

    public int depth(TreeNode root){
        if(root==null)
            return 0;
        int left=depth(root.left);
        int right=depth(root.right);
        return (left>right)?(left+1):(right+1);
    }
}

发表于 2015-12-24 16:08:19 回复(4)
    # 递归判断
    # 以某节点为根的子树平衡需要:该节点平衡&左子树平衡&右子树平衡
    # 判断平衡需要获得左右子树的高度
    # 该函数在某子树平衡时返回其高度,不平衡时返回False
    # 利用and逻辑的短路性质剪枝,可以提前结束
    def IsBalanced_Solution(self, pRoot):
        # write code here
        if not pRoot:  # 空树的高度设为1(避免高度为0和不平衡的False产生歧义)
            return 1
        l = self.IsBalanced_Solution(pRoot.left)
        if not l:  # 如果左子树不平衡
            return False
        r = self.IsBalanced_Solution(pRoot.right)
        if not r:  # 如果右子树不平衡
            return False
        if abs(l-r) < 2:  # 如果左右子树和本节点均平衡,返回该子树高度
            return 1 + max(l,r)
        else:  # 如果本节点不平衡
            return False
编辑于 2019-08-11 20:51:36 回复(1)
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root == null) return true;
        return recur(root) != -1;
    }
    public int recur(TreeNode root) {
        if(root == null) return 0;
        int left = recur(root.left);
        if(left == -1) return -1;
        int right = recur(root.right);
        if(right == -1) return -1;
        return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1;
    }
}
发表于 2022-08-01 19:50:02 回复(0)
def check(node):
    if node is None:
        return 0, True
    
    # 不是叶节点
    if node.left&nbs***bsp;node.right:
        h1, res1 = check(node.left)
        h2, res2 = check(node.right)
        height = max(h1, h2) + 1
        if abs(h1-h2)<=1 and res1 and res2:
            res = True
        else:
            res = False
        return height, res
    # 叶节点
    else:    
        return 1, True

    
class Solution:
    def IsBalanced_Solution(self , pRoot: TreeNode) -> bool:
        # write code here
        return check(pRoot)[1]
O(n)复杂度,同时做计算深度和判断是否平衡

发表于 2022-06-26 14:49:18 回复(0)
import java.lang.*;
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if(root==null) return true;
        return Math.abs(maxDepth(root.left)-maxDepth(root.right))<=1 && IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right) ? true : false;
    }
    public int maxDepth (TreeNode root) {
        // write code here
        if(root==null) return 0;
        return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
    }
}

发表于 2021-11-26 20:25:38 回复(0)
function IsBalanced_Solution(pRoot)
{
    if(pRoot === null){
        return true;
    }
//     左右子树的高度绝对值相差大于1,则不是平衡二叉树
    if(Math.abs(depth(pRoot.left) - depth(pRoot.right)) > 1) return false;
//     进一步判断左右子树是否为平衡二叉树
    return IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
}

// 求二叉树的深度
function depth(node){
    if(node === null){
        return 0;
    }
    let left = depth(node.left);
    let right = depth(node.right);
    return Math.max(left,right) + 1;
}

发表于 2021-10-01 17:19:13 回复(0)