20.5.3
二叉树的深度:
int TreeDepth(TreeNode* root) {
if(!root) return 0;
int left = TreeDepth(root->left);
int right = TreeDepth(root->right);
return (left > right) ? left+1 : right+1; //这里需要+1,漏掉+1会导致部分case错误
}
判断平衡二叉树:
重复遍历:遍历每个节点左右子树的深度
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(!root) return true;
int left = TreeDepth(root->left);
int right = TreeDepth(root->right);
int diff = abs(left - right);
if(diff > 1) return false;
return isBalanced(root->left) && isBalanced(root->right);
}
int TreeDepth(TreeNode* root) {
if(!root) return 0;
int left = TreeDepth(root->left);
int right = TreeDepth(root->right);
return (left > right) ? left+1 : right+1; //这里需要+1,漏掉+1会导致部分case错误
}
};
一次遍历:返回深度的后序遍历
class Solution {
public:
bool isBalanced(TreeNode* root) {
//只需要遍历一次:带深度记录的后序遍历
flag = true;
PostOrder(root);
return flag;
}
int PostOrder(TreeNode* root) {
if(!root) return 0;
int leftDepth, rightDepth;
if(flag) leftDepth = PostOrder(root->left); //此处不需要判断左右子节点存在,因为就是要让它递归到空节点再往回返的!
if(flag) rightDepth = PostOrder(root->right);
if(flag && abs(leftDepth-rightDepth) > 1) {
flag = false;
//return 0;
}
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
private:
bool flag;
};
平衡二叉树,就是左子树深度和右子树深度差最多为1,沿用上一题38题的判断树的深度的代码,在牛客上可以AC
但是其实代码是错误的,因为:只是判断了根节点的左右子树深度差,而平衡二叉树要求任意节点的左右子树高度差不超过1
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot==nullptr) return true;
int leftdepth = TreeDepth(pRoot->left);
int rightdepth = TreeDepth(pRoot->right);
if(abs(leftdepth-rightdepth)<=1) return true;
return false;
}
int TreeDepth(TreeNode* pRoot){
if(pRoot==nullptr) return 0;
return 1+max(TreeDepth(pRoot->left), TreeDepth(pRoot->right));
}
};
正确代码:
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot==nullptr) return true;
int leftdepth = TreeDepth(pRoot->left);
int rightdepth = TreeDepth(pRoot->right);
if(abs(leftdepth-rightdepth)>1) return false;
return (IsBalanced_Solution(pRoot->left)&&IsBalanced_Solution(pRoot->right));
}
int TreeDepth(TreeNode* pRoot){
if(pRoot==nullptr) return 0;
return 1+max(TreeDepth(pRoot->left), TreeDepth(pRoot->right));
}
};
书上的另一种更优的解法:
(从书上的这种解法,我找到了之前38题我使用两个固定指针的先序遍历Bug原因)
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
//int (*pDepth) = 0;
int Depth = 0;
return IsBalanced_Solution(pRoot, &Depth);
}
bool IsBalanced_Solution(TreeNode* pRoot, int* pDepth) {
if(pRoot==nullptr)
{
*pDepth = 0;
return true;
}
//后序遍历,一边遍历求深度,一边判断节点是否为平衡子树
int left, right;
if(IsBalanced_Solution(pRoot->left, &left) && IsBalanced_Solution(pRoot->right, &right))
{
if(abs(left-right)<=1){
*pDepth = 1+max(left, right);
return true;
}
}
return false;
}
};