110. 平衡二叉树(C++)

题目

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

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

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

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

	3
   / \
  9  20
    /  \
   15   7

返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

	   1
	  / \
	 2   2
	/ \
   3   3
  / \
 4   4

返回 false 。

分析与题解

自顶向下递归

定义函数height,用于计算二叉树中的任意一个节点 p的高度:

\[\text { height }(p)=\left\{\begin{array}{l} 0 \\ \max (\text { height }(p . l e f t), \text { height }(p . r i g h t))+1 \end{array}\right.\]

有了计算节点高度的函数,即可判断二叉树是否平衡。具体做法类似于二叉树的前序遍历,即对于当前遍历到的节点,首先计算左右子树的高度,如果左右子树的高度差是否不超过 1,再分别递归地遍历左右子节点,并判断左子树和右子树是否平衡。这是一个自顶向下的递归的过程。

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int getDepth(TreeNode* root){
        if(root==nullptr)
            return 0;
        return max(getDepth(root->left),getDepth(root->right))+1;
    }
    bool isBalanced(TreeNode* root) {
        if(root==nullptr)
            return true;
        int num = abs(getDepth(root->left) - getDepth(root->right));
        if(num<=1)
            return (isBalanced(root->left) && isBalanced(root->right));
        else
            return false;
    }
};

由于是自顶向下递归,因此对于同一个节点,函数getDepth()会被重复调用,算法复杂度为O(n2),时间复杂度较高。

自底向上递归

如果使用自底向上的做法,则对于每个节点,函数只会被调用一次。

求height的代码与求深度的代码类似,只不过再递归求根结点前会进行判断:

  • 左子树结点已经不平衡
  • 右子树结点已经不平衡
  • 左右height差值大于1

满足上三条件任意一种便将根结点也返回-1。根结点最后的返回值其实是自底向上遍历判断所有结点的结果。代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int calHeight(TreeNode* root){
        if(root==nullptr)
            return 0;
        int leftHeight = calHeight(root->left);
        int rightHeight = calHeight(root->right);
        //相比于自顶向下递归,采用自底向上计算高度
        //在计算根结点高度过程中
        //已经对于左右子结点逐层进行平衡树判断
        if(leftHeight==-1 || rightHeight==-1 || abs(leftHeight-rightHeight)>1)
            return -1;
        else
            return max(leftHeight,rightHeight)+1;
        
    }

    bool isBalanced(TreeNode* root) {
        return calHeight(root)!=-1;
    }
};
posted @ 2020-09-02 20:30  脱线森林`  阅读(149)  评论(0编辑  收藏  举报