题目链接:leetcode 104.二叉树的最大深度
文章讲解:代码随想录 104.二叉树的最大深度讲解
视频讲解:二叉树的高度和深度有啥区别?究竟用什么遍历顺序?很多录友搞不懂 | 104.二叉树的最大深度
思路和解法
题目:
给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
想法:
今天的题目在学层序遍历的时候都做过。
方案一:层序遍历,每遍历到新一层的时候,记录深度+1即可。
方案二:递归法,递归获取子树的深度,要注意边界条件的设置,是遍历到空指针返回深度0,然后因为要取最大深度,所以取左右子树中更深的一个,再加上本节点的一层,然后返回结果。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
//使用队列
queue<TreeNode*> que;
//初始化
if (root != nullptr) {
que.push(root);
}
//记录深度
int depth = 0;
//开始遍历 while中每次是一层
while (!que.empty()) {
depth++;
//一定要提前取出元素个数
int size = que.size();
//每层循环是当前层中的一个元素
for (int i = 0; i < size; i++) {
TreeNode* cur = que.front();
que.pop();
if (cur -> left) que.push(cur -> left);
if (cur -> right) que.push(cur -> right);
}
}
return depth;
}
};
class Solution {
public:
int getDepth(TreeNode* node) {
if (node == nullptr) return 0;
int leftDepth = getDepth(node -> left);
int rightDepth = getDepth(node -> right);
int depth = max(leftDepth, rightDepth) + 1;
return depth;
}
int maxDepth(TreeNode* root) {
//使用递归法
int result = getDepth(root);
return result;
}
};
题目链接:leetcode 111.二叉树的最小深度
文章讲解:代码随想录 111.二叉树的最小深度讲解
视频讲解:看起来好像做过,一写就错! | LeetCode:111.二叉树的最小深度
思路和解法
题目:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
想法:
方案一:层序遍历迭代法,因为要取最小深度,所以在层序遍历过程中,遇到第一个叶子节点返回深度即可。
方案二:递归法,要注意的点比较多,虽然是取最小深度,但是必须是到叶子节点的深度,因此只要当前节点有子节点,就要递归获取,如果有两个子节点,就递归获取到叶子节点深度更小的深度。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
//迭代法 好理解
class Solution {
public:
int minDepth(TreeNode* root) {
//使用队列
queue<TreeNode*> que;
//初始化
if (root != nullptr) {
que.push(root);
}
//记录深度
int depth = 0;
//开始遍历 while中每次是一层
while (!que.empty()) {
depth++;
//一定要提前取出元素个数
int size = que.size();
//每层循环是当前层中的一个元素
for (int i = 0; i < size; i++) {
TreeNode* cur = que.front();
que.pop();
if (cur -> left) que.push(cur -> left);
if (cur -> right) que.push(cur -> right);
if (!cur -> left && !cur -> right) {
return depth;
}
}
}
return depth;
}
};
//递归法 后序遍历更容易理解
class Solution {
public:
//递归函数
int getDepth(TreeNode* node) {
//终止条件
if (node == nullptr) {
return 0;
}
//记录深度
int depth = 0;
//如果仅有一个子节点,最小深度还需要向下递归
if (node -> left && !node -> right) {
//向左子节点向下递归
depth = getDepth(node -> left) + 1;
} else if (!node -> left && node -> right) {
//向右子节点向下递归
depth = getDepth(node -> right) + 1;
} else {
//左右子节点都有,取更小的深度
depth = min(getDepth(node -> left), getDepth(node -> right)) + 1;
}
return depth;
}
int minDepth(TreeNode* root) {
return getDepth(root);
}
};
题目链接:leetcode 222.完全二叉树的节点个数
文章讲解:代码随想录 222.完全二叉树的节点个数讲解
视频讲解:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量
思路和解法
题目:
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
想法:
获取节点个数层序遍历可以实现,但是时间复杂度不够好,利用完全二叉树的性质可以更快。这也是本题的考察目的。
完全二叉树的性质:
1、一直向左深入和一直向右深入,两边深度一致的树是满二叉树,完全二叉树向下递归一定会出现满二叉树,最坏的情况就是到叶子节点,也算满二叉树。
2、如果完全二叉树为h层,第h层包含
2
h
−
1
2^{h-1}
2h−1个节点,整棵树包含
2
h
−
1
2^{h}-1
2h−1个节点。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
//讲解提供的代码,注释有用
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;
}
};