LeetCode- 110. 平衡二叉树

110.平衡二叉树

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

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

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

思路

  1. 递归三要素
  • 确定参数和返回值
  • 递归中止条件
  • 递归逻辑部分
  1. 二叉树的深度优先遍历
    二叉树的深度优先遍历有左中右三种, 确定不同遍历方法会有不同的解题逻辑。看清遍历方式就能抓住不同的递归代码的本质。
    很多递归代码的写法不同但是本质上对应的是同一种遍历逻辑。
  2. 平衡二叉树
    叉树每个节点 的左右两个子树的高度差的绝对值不超过 1, 意味着需要遍历二叉树, 需要计算高度差。
    计算高度或二叉树的深度一般使用后序遍历方式, 可以自底向上返回高度。

代码实现

  • 1 经过分析可以知道核心代码是二叉树的后序遍历, 并用递归实现。首先确定参数和返回值, 如直接使用函数isBalanced如下,
    可以继续写出中止条件
class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) return 0; // 空节点对高度贡献0
    }
}
  • 2 感觉返回值不太合适, 这样那就新建一个函数
class Solution {
    private int getDepth(TreeNode root) {
        if (root == null) return 0; // 空节点对高度贡献0
    }
    public boolean isBalanced(TreeNode root) {
    }
}
  • 3 接下来,就是递归逻辑, 后序遍历的递归逻辑分为三个阶段 (1) 访问左子树 (2)访问右子树 (3) 访问中间节点并处理(如打印节点值等操作)
class Solution {
    private int getDepth(TreeNode root) {
        if (root == null) return 0; // 空节点对深度贡献0
        
        // 访问左节点
        int leftH = getDepth(root.left);
        // 访问右节点
        int rightH = getDepth(root.right);
        // 处理中间节点
        +1 // 访问到中间节点应该给深度贡献1

    }
    public boolean isBalanced(TreeNode root) {
    }
}
  • 4 这样基本思路就很清晰了, 然后这里深度返回最大深度,也就是左右子树深度的最大值, 补充完整如下
class Solution {
    private int getDepth(TreeNode root) {
        if (root == null) return 0; // 空节点对深度贡献0
        
        // 访问左节点
        int leftH = getDepth(root.left);
        // 访问右节点
        int rightH = getDepth(root.right);
        // 处理中间节点
        return Math.max(leftH, rightH) + 1;

    }
    public boolean isBalanced(TreeNode root) {
    }
}
  • 5 这样还没有解决题目中的问题, 还需要判断是不是平衡二叉树, 就是高度差这一部分,可以在处理节点部分完成
class Solution {
    private int getDepth(TreeNode root) {
        if (root == null) return 0; // 空节点对深度贡献0
        
        // 访问左节点
        int leftH = getDepth(root.left);
        // 访问右节点
        int rightH = getDepth(root.right);
        // 处理逻辑
        Math.abs(rightH - leftH)
        return Math.max(leftH, rightH) + 1;

    }
    public boolean isBalanced(TreeNode root) {
    }
}
  • 6 每个节点的左右子树高度差都不能超过1, 因此一个自然的想法就是设置标记变量, 记录最大的高度差
class Solution {
    private int maxDepthDiff = 0;

    private int getDepth(TreeNode root) {
        if (root == null) return 0; // 空节点对深度贡献0
        
        // 访问左节点
        int leftH = getDepth(root.left);
        // 访问右节点
        int rightH = getDepth(root.right);
        // 处理逻辑
        maxDepthDiff = Math.abs(rightH - leftH) > maxDepthDiff ? Math.abs(rightH - leftH) : maxDepthDiff;

        return Math.max(leftH, rightH) + 1;

    }
    public boolean isBalanced(TreeNode root) {
    }
}

掌握了解题的核心思路, 代码实现过程中就能一步一步推进, 最终就可以得到题解如下。当然还有很多其他形式和优化的递归代码,掌握本质思路最重要。

题解

class Solution {
    private int maxDepthDiff = 0;

    private int getDepth(TreeNode root) {
        if (root == null) return 0; // 空节点对深度贡献0
        
        // 访问左节点
        int leftH = getDepth(root.left);
        // 访问右节点
        int rightH = getDepth(root.right);
        // 处理逻辑
        maxDepthDiff = Math.abs(rightH - leftH) > maxDepthDiff ? Math.abs(rightH - leftH) : maxDepthDiff;

        return Math.max(leftH, rightH) + 1;

    }
    public boolean isBalanced(TreeNode root) {
        getDepth(root);
        return maxDepthDiff <= 1;
    }
}
posted @ 2021-09-26 23:51  -Rocky-  阅读(65)  评论(0编辑  收藏  举报