我的LeetCode:https://leetcode-cn.com/u/ituring/

我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii

LeetCode 110. 平衡二叉树

题目

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

  • 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过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 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/balanced-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

必须验证根和每一个节点的左右子树高度差:

  • 自顶向下验证每个节点;(会存在重复计算问题)
  • 自底向上验证每个节点,一旦某个子节点不符合即返回,不再计算上层节点;(最多一次计算,最快)

思路1-自顶向下,递归校验

递归计算同层节点左右子树的高度差,存在重复计算;

算法复杂度:

  • 时间复杂度: $ {color{Magenta}{Omicronleft(nlognright)}} $ 计算略复杂:详见复杂度分析
  • 空间复杂度: $ {color{Magenta}{Omicronleft(nright)}} $ 递归栈的深度

思路2-自底向上/二叉树的后序遍历,递归校验

与方法1的唯一区别是从叶子节点开始向上校验同层节点的左右子树高度差,一旦发现差超过1的可以直接返回,跳过对上层节点的计算,速度最快;

算法复杂度:

  • 时间复杂度: $ {color{Magenta}{Omicronleft(nright)}} $ 每个节点最多访问一次
  • 空间复杂度: $ {color{Magenta}{Omicronleft(nright)}} $ 递归栈的深度

算法源码示例

package leetcode;

/**
 * @author ZhouJie
 * @date 2020年1月11日 下午8:32:42 
 * @Description: 110. 平衡二叉树
 *
 */
public class LeetCode_0110 {

}

// Definition for a binary tree node.
class TreeNode_0110 {
	int val;
	TreeNode_0110 left;
	TreeNode_0110 right;

	TreeNode_0110(int x) {
		val = x;
	}
}

class Solution_0110 {
	/**
	 * @author: ZhouJie
	 * @date: 2020年5月18日 下午11:54:54 
	 * @param: @param root
	 * @param: @return
	 * @return: boolean
	 * @Description: 1-对根及左右子树递归计算高度差;
	 *
	 */
	public boolean isBalanced_1(TreeNode_0110 root) {
		// 当前节点为null或者其左右节点的高度差不大于1
		return root == null || isBalanced_1(root.left) && isBalanced_1(root.right)
				&& Math.abs(maxDepth(root.left) - maxDepth(root.right)) < 2;
	}

	/**
	 * @author: ZhouJie
	 * @date: 2020年5月19日 上午11:54:20 
	 * @param: @param root
	 * @param: @return
	 * @return: int
	 * @Description: 计算树高
	 *
	 */
	private int maxDepth(TreeNode_0110 root) {
		return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
	}

	/**
	 * @author: ZhouJie
	 * @date: 2020年5月18日 下午11:55:37 
	 * @param: @param root
	 * @param: @return
	 * @return: boolean
	 * @Description: 2-后续遍历,自底向上校验每层树的高度差,一旦不平衡直接返回,上层节点不再处理;
	 *
	 */
	public boolean isBalanced_2(TreeNode_0110 root) {
		return checkBlance(root) != -1;
	}

	private int checkBlance(TreeNode_0110 root) {
		if (root == null) {
			return 0;
		}
		// 递归计算左右子树的高度,若遇到-1代表树已在某一层已经不平衡,无需再递归了,直接返回
		int left = checkBlance(root.left);
		if (left == -1) {
			return -1;
		}
		int right = checkBlance(root.right);
		if (right == -1) {
			return -1;
		}
		// 一旦任意同层左右子树的高度差大于1就直接返回-1,-1会直接返回,相当于剪枝,避免后面无意义的递归
		return Math.abs(left - right) > 1 ? -1 : Math.max(left, right) + 1;
	}
}

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/izhoujie/p/12916260.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!