左神算法:判断二叉树是否为平衡二叉树(树形dp套路,Java版)

本题来自左神《程序员代码面试指南》“判断二叉树是否为平衡二叉树”题目。

题目

平衡二叉树的性质为:要么是一棵空树,要么任何一个节点的左右子树高度差的绝对值不超过 1。

给定一棵二叉树的头节点 head,判断这棵二叉树是否为平衡二叉树。

要求:如果二叉树的节点数为 N,则要求时间复杂度为 O(N)


题解

平衡二叉树的标准是:对任何子树来说,左子树和右子树的高度差都不超过1。本题解法的整体过程为 树形 dp 套路,请读者先阅读 “找到二叉树中的最大搜索二叉子树” 问题了解这个套路,本题是这个套路的再次展示。

首先,树形dp 套路的前提是满足的。依次考查每个节点为头节点的子树,如果都是平衡二叉树,那么整体就是平衡二叉树。

树形 dp 套路第一步

以某个节点X 为头节点的子树中,分析答案有哪些可能性,并且这种分析是以X 的左子树、X 的右子树和X 整棵树的角度来考虑可能性的。

  • 可能性一:如果 X 的左子树不是平衡的,则以 X 为头节点的树就是不平衡的。
  • 可能性二:如果 X 的右子树不是平衡的,则以 X 为头节点的树就是不平衡的。
  • 可能性三:如果 X 的左子树和右子树高度差超过 1,则以 X 为头节点的树就是不平衡的。
  • 可能性四:如果上面可能性都没中,那么以 X 为头节点的树是平衡的。
树形 dp 套路第二步

根据第一步的可能性分析,列出所有需要的信息。左子树和右子树都需要知道各自是否平衡,以及高度这两个信息。

树形 dp 套路第三步

根据第二步信息汇总。定义信息如 ReturnType 类所示。

树形 dp 套路第四步

设计递归函数。递归函数是处理以X 为头节点的情况下的答案,包括设计递归的 base case,默认直接得到左树和右树所有的信息,以及把可能性做整合,并且也返回第三步的信息结构这四个小步骤。本题的递归实现请看以下的 process 方法,主函数是以下的 isBalanced 方法。


代码

含测试用例

package chapter_3_binarytreeproblem;

public class Problem_13_IsBalancedTree {

	public static class Node {
		public int value;
		public Node left;
		public Node right;

		public Node(int data) {
			this.value = data;
		}
	}

	public static boolean isBalanced(Node head) {
		return process(head).isBalanced;
	}

	public static class ReturnType {
		public boolean isBalanced;
		public int height;

		public ReturnType(boolean isBalanced, int height) {
			this.isBalanced = isBalanced;
			this.height = height;
		}
	}

	public static ReturnType process(Node head) {
		if (head == null) {
			return new ReturnType(true, 0);
		}
		ReturnType leftData = process(head.left);
		ReturnType rightData = process(head.right);
		int height = Math.max(leftData.height, rightData.height) + 1;
		boolean isBalanced = leftData.isBalanced && rightData.isBalanced && Math.abs(leftData.height - rightData.height) < 2;
		return new ReturnType(isBalanced, height);
	}

	public static void main(String[] args) {
		Node head = new Node(1);
		head.left = new Node(2);
		head.right = new Node(3);
		head.left.left = new Node(4);
		head.left.right = new Node(5);
		head.right.left = new Node(6);
		head.right.right = new Node(7);

		System.out.println(isBalanced(head));

	}

}

上一篇:5 - Binary Tree & Tree-based DFS


下一篇:剑指offer-面试题55-II:平衡二叉树