题目来源
题目描述
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:
bool isBalanced(TreeNode* root) {
}
};
题目解析
树的深度 = max(左子树的深度, 右子树的深度) + 1
递归套路求解
分析:如果想要知道以root为根节点的树是不是平衡二叉树,那么它满足如下条件:
- 左子树是平衡二叉树
- 右子树是平衡二叉树
- 自己也是平衡二叉树
判断root是不是平衡二叉树的前提是,root必须从询问它的左右子树:
- 你是不是平衡二叉树
- 你的高度是多少
因此,我们可以定义一个Info:
struct Info{
bool isBalanced;
int height;
explicit Info(bool b, int h) : isBalanced(b), height(h) {
}
};
然后递归求解:
Info process(TreeNode *root){
if(root == nullptr){
return Info(true, 0);
}
// 询问左右子树的信息
Info leftInfo = process(root->left);
Info rightInfo = process(root->right);
// 得出自己的信息
int height = std::max(leftInfo.height, rightInfo.height) + 1;
bool isBalanced = true;
if(!leftInfo.isBalanced) {
isBalanced = false;
}
if(!rightInfo.isBalanced) {
isBalanced = false;
}
if(std::abs(leftInfo.height - rightInfo.height) > 1) {
isBalanced = false;
}
return Info(isBalanced, height);
}
最后调用:
bool isBalanced(TreeNode* root) {
if(root == nullptr){
return true;
}
return process(root).isBalanced;
}
整体代码如下:
class Solution {
struct Info{
bool isBalanced;
int height;
explicit Info(bool b, int h) : isBalanced(b), height(h) {
}
};
Info process(TreeNode *root){
if(root == nullptr){
return Info(true, 0);
}
Info leftInfo = process(root->left);
Info rightInfo = process(root->right);
int height = std::max(leftInfo.height, rightInfo.height) + 1;
bool isBalanced = true;
if(!leftInfo.isBalanced) {
isBalanced = false;
}
if(!rightInfo.isBalanced) {
isBalanced = false;
}
if(std::abs(leftInfo.height - rightInfo.height) > 1) {
isBalanced = false;
}
return Info(isBalanced, height);
}
public:
bool isBalanced(TreeNode* root) {
if(root == nullptr){
return true;
}
return process(root).isBalanced;
}
};
递归解法
首先判断左子树是不是平衡二叉树,然后判断右子树是不是平衡二叉树,最后确定自己是不是平衡二叉树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null){
return true;
}
if (Math.abs(helper(root.left) - helper(root.right)) > 1){
return false;
}
return isBalanced(root.left) && isBalanced(root.right);
}
public int helper(TreeNode root){
if (root == null){
return 0;
}
int left = helper(root.left) ;
int right = helper(root.right);
return Math.max(left, right) + 1;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
if (root == null){
return true;
}
if (!isBalanced(root.left)){
return false;
}
if (!isBalanced(root.right)){
return false;
}
if((Math.abs(helper(root.left) - helper(root.right)) > 1)){
return false;
}
return true;
}
public int helper(TreeNode root){
if (root == null){
return 0;
}
int left = helper(root.left) ;
int right = helper(root.right);
return Math.max(left, right) + 1;
}
}
优化
上面的解法在判断的每一个节点是否是二叉树的时候,都要递归求一遍它的高度。
我们并不需要求每一个树的高度,只要有一个节点的左右子树高度差不满足条件就直接退出即可
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private boolean flag = true;
public boolean isBalanced(TreeNode root) {
if (root == null){
return true;
}
helper(root);
return flag;
}
private int helper(TreeNode root){
if (root == null){
return 0;
}
int left = helper(root.left) ;
int right = helper(root.right);
if (Math.abs(left- right) > 1){
flag = false;
return -1;
}
return Math.max(left, right) + 1;
}
}