zoukankan      html  css  js  c++  java
  • LeetCode 110. 平衡二叉树

    我的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(nlogn ight)}} $ 计算略复杂:详见复杂度分析
    • 空间复杂度: $ {color{Magenta}{Omicronleft(n ight)}} $ 递归栈的深度

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

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

    算法复杂度:

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

    算法源码示例

    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;
    	}
    }
    
    
  • 相关阅读:
    python基础
    目标文件格式
    PHP 计算每个月的最后一天
    学习应该专注于学习这件事上
    以 Composer 的方式在 PhpStorm 中添加代码审查工具 Code Sniffer
    开始在博客园写文章啦!
    Git 常用操作
    常用写作格式
    将公司的主要项目从eclipse迁移到android studio for mac环境(1)
    写随笔、博客的心情
  • 原文地址:https://www.cnblogs.com/izhoujie/p/12916260.html
Copyright © 2011-2022 走看看