剑指 Offer 55

  • 题目描述
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。

 

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

3
/ 
9 20
/ 
15 7
返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

1
/ 
2 2
/ 
3 3
/ 
4 4
返回 false 。
  • 解法一:递归+重复遍历

假如我们对每个节点求其深度,然后再递归地对左右子树均判断其深度差是否>1,则可以判断这棵树是否是平衡二叉树。对于一个节点,其深度为左右子树深度的较大值+1,理解这一点则可以了。

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if not root:
            return True
        if abs(self.treeDepth(root.left) - self.treeDepth(root.right)) >1:
            return False
        return self.isBalanced(root.left) and self.isBalanced(root.right)

    def treeDepth(self, root): #求深度
        if not root:
            return 0
        nLeft = self.treeDepth(root.left)
        nRight = self.treeDepth(root.right)
        if nLeft > nRight:
            return nLeft + 1
        else:
            return nRight + 1

或者这样, 简洁一点的 :

class Solution:
    '''
    递归+重复遍历(平时能想得到)
    '''
    def isBalanced(self, root: TreeNode) -> bool:
        if not root:
            return True
        return abs(self.depth(root.left) - self.depth(root.right))<=1 and self.isBalanced(root.left) and self.isBalanced(root.right)

    def depth(self, root):
        if not root:
            return 0
        return max(self.depth(root.left), self.depth(root.right))+1 
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        
        def depth(root):
            if not root:
                return 0
            else:
                return 1+ max(depth(root.left),depth(root.right))
    
        if not root:
            return True
        if abs(depth(root.left) - depth(root.right)) >1:
            return False
        else:
            return self.isBalanced(root.left) and self.isBalanced(root.right)

但是呢,以上方法存在局限,为什么呢?以上方法需要遍历每一个节点,一个节点会重复遍历多次,因此这样重复的工作会影响性能。

  • 解法二:递归+剪枝

我们只需要从最深层的叶子节点,从下往上遍历,然后每次都判断其左右子树的深度差是否大于1,如果大于1则不是平衡二叉树则直接返回-1,-1表示此树不是平衡而二叉树(这就是所说的“剪枝”)。

class Solution:
    '''
    递归+剪枝
    '''
    def isBalanced(self, root: TreeNode) -> bool:
        def rer(root):
            if not root:
                return 0
            left = rer(root.left)
            if left == -1:
                return -1
            right = rer(root.right)
            if right == -1:
                return -1
            
            return max(left, right) +1 if abs(left-right)<=1 else -1
        return rer(root) != -1 
原文地址:https://www.cnblogs.com/yeshengCqupt/p/13462399.html