平衡二叉树-递归法

1题目

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

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

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

示例 1:

平衡二叉树-递归法_第1张图片

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

输出:true

示例 2:

平衡二叉树-递归法_第2张图片

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

输出:false

示例 3:

输入:root = []

输出:true

2链接

题目:110. 平衡二叉树 - 力扣(LeetCode)

视频:后序遍历求高度,高度判断是否平衡 | LeetCode:110.平衡二叉树_哔哩哔哩_bilibili

3解题思路

强调一波概念:

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数。

  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数。

leetcode中强调的深度和高度是按照节点来计算的,即根节点深度是1,如图:

平衡二叉树-递归法_第3张图片

深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)

递归三步曲分析:

  1. 明确递归函数的参数和返回值

参数:当前传入节点。 返回值:以当前传入节点为根节点的树的高度。

那么如何标记左右子树是否差值大于1呢?

如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。

所以如果已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了。

代码如下:

// -1 表示已经不是平衡二叉树了,否则返回值是以该节点为根节点树的高度
int getHeight(TreeNode* node)
  1. 明确终止条件

递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0

代码如下:

if (node == NULL) {
    return 0;
}
  1. 明确单层递归的逻辑

如何判断以当前传入节点为根节点的二叉树是否是平衡二叉树呢?当然是其左子树高度和其右子树高度的差值。

分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。

代码如下:

int leftHeight = getHeight(node->left); // 左
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->right); // 右
if (rightHeight == -1) return -1;

int result;
if (abs(leftHeight - rightHeight) > 1) {  // 中
    result = -1;
} else {
    result = 1 + max(leftHeight, rightHeight); // 以当前节点为根节点的树的最大高度
}

return result;

总体来说,这个函数使用了递归的思想,通过逐层遍历节点,计算每个节点的左右子树高度,并比较左右子树高度差是否超过 1,从而判断整棵二叉树是否平衡。如果是平衡二叉树,则返回其高度;否则返回 -1。

4代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

 //迭代法-后序遍历
class Solution {
public:
    // 判断二叉树是否平衡的函数,输入参数为根节点指针
    int getHeight(TreeNode* root) {
        // 若当前节点为空,返回 0
        if (root == nullptr) return 0;
        // 递归遍历左子树,并获取其高度
        int leftHeight = getHeight(root->left);
        // 如果左子树不平衡,则返回 -1
        if (leftHeight == -1) return -1;
        // 递归遍历右子树,并获取其高度
        int rightHeight = getHeight(root->right);
        // 如果右子树不平衡,则返回 -1
        if (rightHeight == -1) return -1;
        // 定义变量 result 为当前节点的高度,初始化为0
        int result = 0;
        // 如果当前节点的左右子树高度差大于 1,则返回 -1 表示不平衡
        if (abs(leftHeight - rightHeight) > 1) result = -1;
        // 否则返回当前节点的高度,即左右子树中最高的那个的高度加上 1
        else result = 1 + max(leftHeight, rightHeight);
        return result;
    }

    bool isBalanced(TreeNode* root) {
        return getHeight(root) == -1 ? false : true;
    }
};

你可能感兴趣的:(LeetCode练习,算法,leetcode,c++)