题目10:110. 平衡二叉树
同类题目
前置知识
- 无
题目描述
给定一个二叉树,判断它是否是
平衡二叉树
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:true
示例 2:
输入:root = [1,2,2,3,3,null,null,4,4]
输出:false
示例 3:
输入:root = []
输出:true
提示:
- 树中的节点数在范围
[0, 5000]内 -104 <= Node.val <= 104
思路分析
本题使用子问题分解(分治)思想来求解
首先考虑,如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点交给框架,递归函数会帮你在所有节点上执行相同的操作。
本题要返回左右子树的高度后,进行比较高度的差值,如果大于1,则不是平衡二叉树,因此是后续位置。
针对某一个单独的节点,有哪些事情要做?
- 比较左右子树返回的高度是否大于1
- 返回
1 + max(leftheight, rightheight)
程序代码
方法一:使用一个全局变量记录是否是平衡树
//https://leetcode.cn/problems/balanced-binary-tree/description/
//110. 平衡二叉树
#include<iostream>
#include<vector>
using namespace std;
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 {
private:
bool balance = true;
public:
int travel(TreeNode* root)
{
if(root == nullptr)
{
return 0;
}
int leftdep = travel(root->left);
int rightdep = travel(root->right);
// 如果左右的深度大于1 则记录不是平衡树
if(abs(leftdep - rightdep) > 1)
{
balance = false;
}
return 1 + max(leftdep,rightdep);
}
bool isBalanced(TreeNode* root) {
travel(root);
return balance;
}
};
复杂度分析
时间复杂度:O(n),其中n是二叉树中的节点个数。使用自底向上的递归,每个节点的计算高度和判断是否平衡都只需要处理一次,最坏情况下需要遍历二叉树中的所有节点,因此时间复杂度是 O(n)。
空间复杂度:O(n),其中 n 是二叉树中的节点个数,二叉树最坏情况下退化为单链表。
程序代码
方法二:使用一个特殊值-1,记录是否是平衡树
class Solution {
public:
int travel(TreeNode* root)
{
if(root == nullptr)
{
return 0;
}
int leftdep = travel(root->left);
int rightdep = travel(root->right);
// 如果不是平衡树大于1,则返回-1
if(leftdep == -1 || rightdep == -1 || abs(leftdep - rightdep) > 1)
{
return -1;
}
// 返回子树的高度
return 1 + max(leftdep,rightdep);
}
bool isBalanced(TreeNode* root) {
return travel(root) != -1;
}
};
程序代码
方法三:判断left 后,如果为-1 可以提前退出
class Solution {
public:
int travel(TreeNode* root)
{
if(root == nullptr)
{
return 0;
}
int leftdep = travel(root->left);
// 左子树如果是-1,可以直接退出了,不需要继续递归
if(leftdep == -1 )
{
return -1;
}
int rightdep = travel(root->right);
if(rightdep == -1 || abs(leftdep - rightdep) > 1)
{
return -1;
}
return 1 + max(leftdep,rightdep);
}
bool isBalanced(TreeNode* root) {
return travel(root) != -1;
}
};
三次优化后的时间提升很明显
题目感悟
最初的方法中一直纠结怎么不使用全局变量,在递归的函数中直接判断,因为全局变量一个很多的缺点是要全部都跑一遍,最后才能判断出来结果,时间就上去了。
方法二中使用了一个特殊的值,解决了这个问题,能够提前返回后,程序就快了很多。
更多相关知识:github.com/pingguo1987…