第一题: 104.二叉树的最大深度 (优先掌握递归)
这道题既可以采用迭代法又可以采用递归法,递归法其实比较容易想到,只要按照递归三部曲的步骤来就能够解决,代码如下:
①递归法:
class Solution {
public:
int maxDepth(TreeNode* root) {
if(!root) return 0;
return max(maxDepth(root->left) + 1, maxDepth(root->right) + 1);
}
};
迭代法则与层序遍历相关联,可以使用层序遍历的模板,每一层遍历完成后就让depth++,最后return返回结果即可,代码如下:
②迭代法(层序遍历法):
class Solution {
public:
int maxDepth(TreeNode* root) {
queue<TreeNode*> que;
int depth = 0;
if(root) que.push(root);
while(!que.empty()) {
int size = que.size();
while(size--) {
auto node = que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
depth++;
}
return depth;
}
};
第二题: 111.二叉树的最小深度 (优先掌握递归)
同理,这道题也可以采用递归法和迭代法。迭代法同样用到了层序遍历,解法与上一题相同,代码如下:
①递归法:
class Solution {
public:
int minDepth(TreeNode* root) {
if(!root) return 0;
int res = 0;
if(root->left && !root->right) res = minDepth(root->left) + 1;
else if(!root->left && root->right) res = minDepth(root->right) + 1;
else res = min(minDepth(root->left), minDepth(root->right)) + 1;
return res;
}
};
②迭代法(层序遍历法):
class Solution {
public:
int minDepth(TreeNode* root) {
int res = 0;
queue<TreeNode*> que;
if(root)
que.push(root);
while(!que.empty()) {
res++;
int size = que.size();
while(size--) {
TreeNode* node = que.front();
que.pop();
if(!node->left && !node->right)
return res;//这里直接返回
if(node->left)
que.push(node->left);
if(node->right)
que.push(node->right);
}
}
return res;//走不到这一行
}
};
第三题: 222.完全二叉树的节点个数(优先掌握递归)
这道题同样可以采用递归和迭代两种方法来解决,如果没有考虑到完全二叉树的特性,只把这道题当作普通二叉树来求解,那么递归法和迭代法(层序遍历法)都需要遍历到每一个节点,时间复杂度为O(n)。如果能够考虑到完美二叉树的特性,那就能够降低算法的时间复杂度。也就是说,其实可以发现,满二叉树的节点数量为.
对于完全二叉树而言只有两种情况:情况一是满二叉树,情况二是最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。
①递归法:
class Solution {
public:
int countNodes(TreeNode* root) {
if (root == nullptr) return 0;
TreeNode* left = root->left;
TreeNode* right = root->right;
int leftDepth = 0, rightDepth = 0; // 这里初始为0是有目的的,为了下面求指数方便
while (left) { // 求左子树深度
left = left->left;
leftDepth++;
}
while (right) { // 求右子树深度
right = right->right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1; // 注意(2<<1) 相当于2^2,所以leftDepth初始为0
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
};
考虑到完全二叉树的特性,这样写出的算法,时间和空间复杂度都是O(logn).
②迭代法(层序遍历):
class Solution {
public:
int countNodes(TreeNode* root) {
queue<TreeNode*> que;
int cnt = 0;
if(root) {
que.push(root);
cnt++;
}
while(!que.empty()) {
int size = que.size();
while(size--) {
auto node = que.front();
que.pop();
if(node->left) {
que.push(node->left);
cnt++;
}
if(node->right) {
que.push(node->right);
cnt++;
}
}
}
return cnt;
}
};
第四题: 559.n叉树的最大深度
递归法解题最为方便!
class Solution {
public:
int maxDepth(Node* root) {
if(!root) return 0;
int size = root->children.size();
int res = 0;
for(int i = 0; i < size; ++i) {
res = max(res, maxDepth(root->children[i]));
}
return res + 1;
}
};
Day16打卡!!!