[LeetCode110. 平衡二叉树] | 刷题打卡

294 阅读2分钟

一、题目描述:

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

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

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例 1:

输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例 3:

输入:root = []
输出:true

二、思路分析:

有自顶向下和自底向上两种思路,可以分别看成先序遍历和后续遍历。 自顶向下:从根节点向下遍历所有节点,并且计算出每个节点的深度,如果有左右字数高度大于1的说明不是平衡二叉树

  • 时间复杂度 O(Nlog2N): 最差情况下, isBalanced(root) 遍历树所有节点占用 O(N),判断每个节点的最大高度 getTreeHeight(root) 需要遍历 各子树的所有节点 ,子树的节点数的复杂度为O(log2N)
  • 空间复杂度 O(N): 最差情况下(树退化为链表时),系统递归需要使用 O(N) 的栈空间。

自底向上:后续遍历,先访问左右子书,再判断根节点。这样的遍历方式避免了重复计算子树的高度

  • 时间复杂度 O(N): N 为树的节点数;最差情况下,需要递归遍历树的所有节点。
  • 空间复杂度 O(N): 最差情况下(树退化为链表时),系统递归需要使用 O(N) 的栈空间。

三、AC 代码:

class Solution {
    fun isBalanced(root: TreeNode?): Boolean {
        return solution2(root)
    }

    // 后续遍历
    fun solution2(root: TreeNode?): Boolean {
        return depth(root) != -1
    }

    fun depth(root: TreeNode?): Int {
        if (root == null) {
            return 0
        }
        var left = depth(root.left)
        if (left == -1) {
            return -1
        }
        val right = depth(root.right)
        if (right == -1) {
            return -1
        }

        if (Math.abs(left - right) < 2) {
            return Math.max(left, right) + 1
        } else {
            return -1
        }
    }

    fun solution1(root: TreeNode?): Boolean {
        if (root == null) {
            return true
        }

        return isBalanced(root.left) && isBalanced(root.right)
                && Math.abs(getTreeHeight(root.left) - getTreeHeight(root.right)) <= 1
    }

    private fun getTreeHeight(root: TreeNode?): Int {
        if (root == null) {
            return 0
        }

        return Math.max(getTreeHeight(root.left), getTreeHeight(root.right)) + 1
    }
}

四、总结:

如果直接考二叉树的前中后序遍历,应该很多人都能知道。相当一部分题就是变着花样考察二叉树的遍历。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看活动详情