剑指 Offer 55 - II. 平衡二叉树
- 题目描述
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过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