剑指 Offer 55 - II. 平衡二叉树
最容易想到的办法是先序遍历,从顶至底判断每个子树是不是平衡二叉树。
缺点是产生大量重复计算,代码如下。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public boolean isBalanced(TreeNode root) { if (root == null) return true; return isBalanced(root.left) && isBalanced(root.right) && (Math.abs(depth(root.left) - depth(root.right)) <= 1); } int depth(TreeNode root){ if(root == null) return 0; return Math.max(depth(root.left), depth(root.right)) + 1; } }
K神给的最佳解法:
后序遍历 + 剪枝 (从底至顶)
觉得函数的设计很巧妙,recur函数返回的依然是深度,不用向上面加一个depth函数。
同时使用-1判断子树是否平衡,一旦出现不平衡情况直接剪枝,在isBlanced的用返回值是否为-1判断是否是平衡二叉树。
最终返回只有两种情况,一种是树的深度,另一种是-1。
相当于是在 剑指 Offer 55 - I. 二叉树的深度 进行的过程中得到了本题的解。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { //只用判断返回值是不是-1,即在子树中有没有出现过不平衡 public boolean isBalanced(TreeNode root) { return recur(root) != -1; } //后序遍历加剪枝,实现从底向上返回高度 int recur(TreeNode root){ //当遍历越过叶结点,返回高度0 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; //当前是平衡二叉树就返回高度 //不是返回-1,然后由上面返回-1给isBlanced return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1; } }