判断一棵二叉树是否为平衡二叉树:
LeetCode:110.平衡二叉树;
剑指offer:平衡二叉树
- 用递归函数处理二叉树是否平衡的判断问题:
- 原因:因为递归函数很强大。对于二叉树的递归遍历而言,每个二叉树节点都会函数访问3次,分别是“一开始”、“其左子树遍历完之后”和“其右子树遍历完之后”。因而我们可以利用这样的性质来规划我们的函数
- 递归过程要返回给父节点的信息:子树是否平衡、子树高度
- 具体递归方法:
- 先构造这样一个数据结构(class),它包含子树是否平衡(.isB)、子树高度(.h)两个属性,专门用于递归函数的返回值类型。其实就相当于搞了个类,将这俩数据封装起来。如果不创建类,直接返回一个(boolean, int)元组,则更轻松愉快!
- 然后分析一下:二叉树平衡与否,共存在几种情况?
- 遍历到的这个节点为空:isB = True, h = 0(空子树必平衡)
- 遍历到的这个节点左子树不平衡:isB = False, h = 任意(此时h其实是用不到的,因为最后直接返回的是False了)
- 遍历到的这个节点右子树不平衡:isB = False, h = 任意
- 左右子树均平衡的情况下,左右子树高度差>1:isB = False, h = 任意
- 左右子树均平衡的情况下,左右子树高度差<1:isB = True, h = 左右子树高度最大值+1
- 递归code就按照这个思路来写。判断左右子树是否平衡前,先调用递归函数,传入当前节点node.left/node.right,然后根据返回的含有isB和h两个属性的isB属性判断左右子树到底平不平衡
- 为何不直接搞一个函数isBalance(node),每次判断直接传入node.left得到True or False?因为一旦子树平衡,我们还要用到子树高度h呢…
- 最后原主函数返回递归函数的调用结果的”isB”属性。对应元组中第一个布尔类型变量
最后,code奉上:
# 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):
"""
:type root: TreeNode
:rtype: bool
"""
return self.process(root)[0]
def process(self, node):
if node is None:
return True, 0
leftData = self.process(node.left)
if not leftData[0]:
return False, 0
rightData = self.process(node.right)
if not rightData[0]:
return False, 0
if abs(leftData[1] - rightData[1]) > 1:
return False, 0
return True, max(leftData[1], rightData[1])+1