剑指Offer:平衡二叉树
题目:
分析
平衡二叉树:它是一棵空树,或者它的左右子树的高度差的绝对值不超过 1,并且它的左右子树也是平衡二叉树。
解法一
我能想到的最直接的递归解法如下:
class Solution {
public:
map<TreeNode*, int> node_deepth;
bool IsBalanced_Solution(TreeNode* pRoot) {
if (pRoot == nullptr) return true;
return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right)
&& abs(getHeight(pRoot->left) - getHeight(pRoot->right)) <= 1;
}
int getHeight(TreeNode* node) {
if (node == nullptr) return 0;
if (node_deepth.find(node) != node_deepth.end()) return node_deepth[node];
node_deepth[node] = 1 + max({getHeight(node->left), getHeight(node->right)});
return node_deepth[node];
}
};
加了一个 node_deepth 表,避免重复求高度。
解法二
向底向下方法:
- 在求高度的时候判断是否是平衡二叉树,如果不是,则高度返回 -1。
- 如果左右子树中有一个返回了 -1,这个树的高度就是 -1。
- 如果根结果返回的是 -1,则不是平衡二叉树,如果是一个正常的高度,那就是平衡二叉树。
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
return getDeepth(pRoot) != -1;
}
int getDeepth(TreeNode* node) {
if (node == nullptr) return 0;
int leftDeepth = getDeepth(node->left);
int rightDeepth = getDeepth(node->right);
if (leftDeepth == -1 || rightDeepth == -1 || abs(leftDeepth - rightDeepth) > 1)
return -1;
return max({leftDeepth, rightDeepth}) + 1;
}
};
进一步改进一下:把上面代码的顺序变一下,就相当于加了个剪枝。
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
return getDeepth(pRoot) != -1;
}
int getDeepth(TreeNode* node) {
if (node == nullptr) return 0;
int leftDeepth = getDeepth(node->left);
if (leftDeepth == -1) return -1;
int rightDeepth = getDeepth(node->right);
if (rightDeepth == -1) return -1;
if (abs(leftDeepth - rightDeepth) > 1) return -1;
return max({leftDeepth, rightDeepth}) + 1;
}
};