剑指offer39_平衡二叉树_题解

平衡二叉树

题目描述

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

在这里,我们只需要考虑其平衡性,不需要考虑其是不是排序二叉树

平衡二叉树(Balanced Binary Tree),具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

示例1

输入

{1,2,3,4,5,6,7}

返回值

true

分析

方案一:递归(自顶向下)

IsBalanced_Solution函数:判断树root是否平衡

TreeDepth函数:计算树root的深度

代码

/**
1.时间复杂度:O(nlogn)
每层执行复杂度:O(n)
层数复杂度:O(logn)
总体时间复杂度=每层执行复杂度*层数复杂度=O(n*logn)
2.空间复杂度:O(n)
最差情况下(树退化为链表时),系统递归需要使用 O(n) 的栈空间。
**/
class Solution
{
public:
    int TreeDepth(TreeNode *pRoot)
    {
        if (!pRoot)
        {
            return 0;
        }
        return 1 + max(TreeDepth(pRoot->left), TreeDepth(pRoot->right));
    }
    bool IsBalanced_Solution(TreeNode *pRoot)
    {
        if (!pRoot)
        {
            return true;
        }
        return abs(TreeDepth(pRoot->left) - TreeDepth(pRoot->right)) <= 1 && IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);
    }
};

方案二:后序遍历(自底向上)

recur函数:当节点root左右子树的深度差<=1返回当前子树的深度;当节点root左右子树的深度差>2则返回-1,代表此子树不是平衡二叉树

isBalanced函数:若recur(root)!=-1,则说明此树平衡

代码

/**
1.时间复杂度:O(n)
2.空间复杂度:O(n)
**/
class Solution
{
public:
    //用left,right记录root左右子节点的深度,避免遍历root时对左右节点的深度进行重复计算。
    int recur(TreeNode *root)
    {
        //用后序遍历的方式遍历二叉树的每个节点(从底至顶),先左子树,再右子树,最后根节点
        if (!root)
            return 0;
        int left = recur(root->left);
        //若出现节点的深度为-1,则进行剪枝,开始向上返回,之后的迭代不再进行
        if (left == -1)
            return -1;
        int right = recur(root->right);
        //若出现节点的深度为-1,则进行剪枝,开始向上返回,之后的迭代不再进行
        if (right == -1)
            return -1;
        return abs(left - right) <= 1 ? max(left, right) + 1 : -1;
    }
    bool IsBalanced_Solution(TreeNode *pRoot)
    {
        return recur(pRoot) != -1;
    }
};
posted @ 2021-01-14 15:16  RiverCold  阅读(77)  评论(0)    收藏  举报