文章目录
1. 题目来源
链接:I. 二叉树的深度
链接:II. 平衡二叉树
来源:LeetCode——《剑指-Offer》专项
2. 题目说明
3. 题目解析 — I. 二叉树的深度
方法一:递归+常规解法
从根节点开始遍历:
- 若仅有根节点,则深度为 1
- 若根节点只有左子树没有右子树,则深度为左子树深度 +1
- 若根节点只有右子树没有左子树,则深度为左子树深度 +1
- 若左右子树均存在,则该树的深度为其左子树、右子树的深度的较大值再 +1
这样就可以采用递归的思路进行实现了。
参见代码如下:
// 执行用时 :16 ms, 在所有 C++ 提交中击败了46.43%的用户
// 内存消耗 :21.4 MB, 在所有 C++ 提交中击败了100.00%的用户
/**
* 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 maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return (left > right) ? (left + 1) : (right + 1);
}
};
4. 题目解析 — II. 平衡二叉树
方法一:递归+常规解法
有了求二叉树的深度的经验之后再解决这个问题,我们很容易就能想到一个思路:
- 在遍历树的每个结点的时候,调用函
maxDepth
得到它的左右子树的深度 - 如果每个结点的左右子树的深度相差都不超过 1,按照定义它就是一棵平衡的二叉树。
参见代码如下:
// 执行用时 :16 ms, 在所有 C++ 提交中击败了79.85%的用户
// 内存消耗 :22.7 MB, 在所有 C++ 提交中击败了100.00%的用户
/**
* 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:
bool isBalanced(TreeNode* root) {
if (root == nullptr) return true;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
int diff = left - right;
if (diff > 1 || diff < -1) return false;
return isBalanced(root->left) and isBalanced(root->right);
}
int maxDepth(TreeNode* root) {
if (root == nullptr) return 0;
int left = maxDepth(root->left);
int right = maxDepth(root->right);
return (left > right) ? (left + 1) : (right + 1);
}
};
方法二:递归优化+巧妙解法
以上面的方法,代码固然简洁,但我们也要注意到该递归使得一个结点会被重复遍历多次,这种思路的时间效率不高。
后序遍历:当使用后序遍历的时候,遍历到一个节点之前,就已经遍历了它的左右子树,只要在遍历每个节点的时候记录它的深度(某一节点的深度等于它到叶节点的路径的长度),我们就能够一边遍历一边判断每个结点是不是平衡的。
// 执行用时 :12 ms, 在所有 C++ 提交中击败了93.83%的用户
// 内存消耗 :23.7 MB, 在所有 C++ 提交中击败了100.00%的用户
/**
* 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:
bool isBalanced(TreeNode* root) {
int depth = 0;
return help(root, &depth);
}
bool help(TreeNode* root, int* pDepth) {
if (root == nullptr) {
*pDepth = 0;
return true;
}
int left;
int right;
if (help(root->left, &left) and help(root->right, &right)) {
int diff = left - right;
if (diff <= 1 and diff >= -1) {
*pDepth = 1 + (left > right ? left : right);
return true;
}
}
return false;
}
};