LeetCode- 110. 平衡二叉树
110.平衡二叉树
题目链接
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
思路
- 递归三要素
- 确定参数和返回值
- 递归中止条件
- 递归逻辑部分
- 二叉树的深度优先遍历
二叉树的深度优先遍历有左中右三种, 确定不同遍历方法会有不同的解题逻辑。看清遍历方式就能抓住不同的递归代码的本质。
很多递归代码的写法不同但是本质上对应的是同一种遍历逻辑。 - 平衡二叉树
叉树每个节点 的左右两个子树的高度差的绝对值不超过 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;
}
}