题意
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
解法1—后序遍历(左右根)+剪枝,从底至顶
对二叉树做后序遍历(即左右根的遍历顺序),从底至顶返回子树的深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。
算法流程
recur(root)
函数:
- 返回值:
- 当节点root 左 / 右子树的深度差 ≤1 :则返回当前子树的深度,即节点 root 的左 / 右子树的深度最大值 +1 ( max(left, right) + 1 );
- 当节点root 左 / 右子树的深度差 >1 :则返回 −1 ,代表 此子树不是平衡树 。
- 终止条件:
- 当 root 为空:说明越过叶节点,因此返回高度 0 ;
- 当左(右)子树深度为 −1 :代表此树的 左(右)子树 不是平衡树,因此剪枝,直接返回 -1 ,就没必要继续往下执行了。
isBalanced(root)
函数:
- 返回值: 若
recur(root) != -1
,则说明此树平衡,返回 true ; 否则返回 false 。
C++实现
/**
* 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 recur(TreeNode* root)
{
// 如果root为空,说明越过叶子节点,返回高度0
if(NULL==root)
return 0;
int left = recur(root->left);//递归左子树,求左子树高度
if(-1==left) // 如果root的左子树不是平衡树,就进行剪枝,直接返回-1,没必要再往下执行了
return -1;
int right = recur(root->right);//递归右子树,求右子树高度
if(-1==right)
return -1; // 如果root的右子树不是平衡树,就进行剪枝,直接返回-1,没必要再往下执行了
if(abs(left-right)>1)//如果左右子树高度相差大于1,就代表此树不是平衡树,直接返回-1
return -1;
else
return max(left,right)+1; //否则,返回root为根节点的树的高度
}
bool isBalanced(TreeNode* root)
{
if(NULL==root)
return true;
return recur(root)!=-1;
}
};
法2—前序遍历(根左右)+判断深度,从顶至底
- 先构造一个获取当前子树的深度的函数
depth(root);
然后,通过比较某子树的左右子树的深度差 abs(depth(root.left) - depth(root.right)) <= 1 是否成立,来判断某子树是否是二叉平衡树。
再判断该子树的左右子树是否平衡,若所有子树都平衡,则此树平衡。
C++实现
/**
* 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 recur(TreeNode* root)
{
// 如果root为空,说明越过叶子节点,返回高度0
if(NULL==root)
return 0;
int left = recur(root->left);//递归左子树,求左子树高度
if(-1==left) // 如果root的左子树不是平衡树,就进行剪枝,直接返回-1,没必要再往下执行了
return -1;
int right = recur(root->right);//递归右子树,求右子树高度
if(-1==right)
return -1; // 如果root的右子树不是平衡树,就进行剪枝,直接返回-1,没必要再往下执行了
if(abs(left-right)>1)//如果左右子树高度相差大于1,就代表此树不是平衡树,直接返回-1
return -1;
else
return max(left,right)+1; //否则,返回root为根节点的树的高度
}
int depth(TreeNode* root)
{
if(NULL==root)
return 0;
int left_depth = depth(root->left);
int right_depth = depth(root->right);
return max(left_depth,right_depth)+1;
}
bool isBalanced(TreeNode* root)
{
if(NULL==root)
return true;
// 法1
// return recur(root)!=-1;
//法2
int left_depth = depth(root->left); //该树左子树高度
int right_depth=depth(root->right); //该树右子树高度
bool flag = abs(left_depth-right_depth)<=1; //该树左右子树差是否≤1
bool left_tree_balance = isBalanced(root->left); //该树左子树是不是平衡二叉树
bool right_tree_balance = isBalanced(root->right); //该树右子树是不是平衡二叉树
return flag&&left_tree_balance&&right_tree_balance;
}
};