vlambda博客
学习文章列表

经典二叉树知识点:平衡二叉树

昨天和同事散步的时候聊了一会儿平衡二叉树的判断,我很喜欢这个沟通的过程。于是我决定以后每做一道算法题就以能给别人讲解清楚为目的写一篇文章总结下来,希望能给自己和别人带来一些帮助。尝试一下吧。

判断平衡二叉树是一道经典的二叉树题目。甚至平衡二叉树的定义本身就是二叉树的一个知识点,因为面试官一听你连平衡二叉树的定义是什么都不知道,直接就摸透了你的底,留给你的下一句话可能就是:你回去等消息吧~

leetcode110:https://leetcode-cn.com/problems/balanced-binary-tree/

题意

题意通过翻译英文来描述。陈述题意的同时,可以学习一下英语。一举两得。

Given a binary tree, determine if it is height-balanced.

  • determine  v.确定,决定,判定。

语法分析:后半句determine if it is height-balanced.是一个名词性从句,if引导的从句在句子中做determine的宾语成分。

翻译:给一个二叉树,判断他是否是高度平衡的。

For this problem, a height-balanced binary tree is defined as:

翻译:对于这个问题,一个高度平衡的二叉树的定义如下:

a binary tree in which the left and right subtrees of every node differ in height by no more than 1.

翻译:二叉树中的每个节点的的左右子树的高度差不超过1。

思路

这道题的关键点在于需要判断每个节点的左右子树高度的差,这样就引申出了后序遍历,因为只有在优先知道左右子树的高度才能去判断他们的差是否超过一。这是这道题的大体框架。

然后接着思考,我们还需要写一个判断每一个节点高度的工具方法,提供给大体框架来使用。

一个节点的高度的概念在这里是这个节点最长的那一条路径,所以需要判断这个节点的左右节点高度,取最高的那一个,那么这里又是一个后序遍历。

我们在获取左右节点高度的时候就已经知道他们的差是否超过了1,一旦存在这种情况可以直接返回false来解决问题了,正常的话我们依然返回节点的高度就好了。

其实这样思考下来,我们在根节点获取高度判断是否超过一,然后在获取高度的时候顺便就判断了他们的子节点是否是高度平衡的了。

编码

class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
        int leftDepth = getDepth(root.left, 0);
        if(leftDepth < 0) {
            return false;
        }
        int rightDepth = getDepth(root.right, 0);
        if(rightDepth < 0) {
            return false;
        }

        return abs(leftDepth - rightDepth) > 1 ? false : true;
    }

    private int getDepth(TreeNode root, int currentDepth) {
        if(root == null) {
            return currentDepth;
        }

        int leftDepth = getDepth(root.left, currentDepth + 1);
        if(leftDepth < 0) {
            return -1;
        }
        int rightDepth = getDepth(root.right, currentDepth + 1);
        if(rightDepth < 0) {
            return -1;
        }
        if(abs(leftDepth - rightDepth) > 1) {
            return -1;
        }
        return leftDepth > rightDepth ? leftDepth : rightDepth;
        
    }

    private int abs(int a) {
        return a > 0 ? a : -a;
    }
 
    
}

总结

这道题综合体上还是二叉树经典套路的后序遍历。