104.二叉树的最大深度
层序遍历打十个之一。使用一个变量记录层数,遍历每一层的时候该变量+1即可。
层序遍历写法:
int maxDepth0(TreeNode* root) {
if (!root)
return 0;
TreeNode* cur;
queue<TreeNode*> que;
int size;
int ans = 0;
que.push(root);
while (!que.empty()) {
++ans;
size = que.size();
while (size--) {
cur = que.front();
que.pop();
if (cur->left)
que.push(cur->left);
if (cur->right)
que.push(cur->right);
}
}
return ans;
}
递归遍历思路:
· 返回值类型:使用int型返回深度值
· 传入参数:传入一个节点指针
· 终止条件:遇到空节点则向上返回0
· 单层逻辑:计算左右子树的深度,取较大值即可
递归写法:
int getHeight(TreeNode* cur) {
if (!cur)
return 0;
int left = getHeight(cur->left);
int right = getHeight(cur->right);
int height = std::max(left, right) + 1;
return height;
}
int maxDepth(TreeNode* root) {
return getHeight(root);
}
559.N叉树的最大深度
与二叉树最大深度思路一致,每一层迭代/递归时遍历所有节点即可
层序遍历写法:
int maxDepth(Node* root) {
if (!root)
return 0;
Node* cur;
queue<Node*> que;
int size;
int ans = 0;
que.push(root);
while (!que.empty()) {
++ans;
size = que.size();
while (size--) {
cur = que.front();
que.pop();
for (auto child : cur->children) {
if (child)
que.push(child);
}
}
}
return ans;
}
111.二叉树的最小深度
注意最小深度的定义,一定要到达叶节点才能算最小深度,即存在左/右任一子树不能直接返回。
层序遍历的判断条件比较简单,存在两个孩子与只存在某一个节点的逻辑可以写在一起
层序遍历写法:
int minDepth(TreeNode* root) {
if (!root)
return 0;
queue<TreeNode*> que;
int size;
int min = 0;
TreeNode* cur;
que.push(root);
while (!que.empty()) {
++min;
size = que.size();
while (size--) {
cur = que.front();
que.pop();
// 存在任一孩子说明不是叶子节点
if (cur->left || cur->right) {
if(cur->left)
que.push(cur->left);
if(cur->right)
que.push(cur->right);
}
// 发现叶子节点直接返回当前深度
else {
return min;
}
}
}
return min;
}
递归写法需要对每种情况进行分类讨论,对于空孩子不计入。
个人认为写起来做好分类讨论即可,不要被前中后序给束缚住思路。
递归遍历写法:
int getHeight(TreeNode* cur) {
if (!cur)
return 0;
int height;
// 只有一边子树为空时,该子树不记录
if (cur->left && !cur->right)
height = getHeight(cur->left) + 1;
else if (!cur->left && cur->right)
height = getHeight(cur->right) + 1;
else if (cur->left && cur->right) {
int left = getHeight(cur->left);
int right = getHeight(cur->right);
height = std::min(left, right) + 1;
}
// 左右子树都为空,该节点为叶节点,其高度为1
else {
height = 1;
}
return height;
}
int minDepth(TreeNode* root) {
return getHeight(root);
}
222.完全二叉树的节点个数
普通二叉树递归思路:
· 返回值:使用int型返回节点个数
· 传入参数:传入一个节点指针
· 终止条件:遇到空节点返回节点个数0
· 单层逻辑:分别计算当层节点左右子树的节点数,再算上自己1个节点进行返回
int getNum(TreeNode* cur) {
if (!cur)
return 0;
int left = getNum(cur->left); // 左
int right = getNum(cur->right); // 右
int num = left + right + 1; // 中
return num;
}
int countNodes(TreeNode* root) {
int ans = getNum(root);
return ans;
}
利用完全二叉树性质的思路:
完全二叉树中大部分子树都是满二叉树,而满二叉树的节点数能够使用公式计算
· 返回值:使用int型返回节点个数
· 传入参数:传入一个节点指针
· 终止条件:
1、遇到空节点返回节点个数0
2、如果该子树是一个满二叉树,直接使用公式计算其节点数并返回
· 单层逻辑:分别计算当层节点左右子树的节点数,再算上自己1个节点进行返回
int getNum(TreeNode* cur) {
// 以下都是返回条件
// 返回条件除了判断是否是空节点外还有判断该子树是否是满二叉树
if (!cur)
return 0;
TreeNode* left = cur->left;
TreeNode* right = cur->right;
int leftDepth = 1;
int rightDepth = 1;
// 一路向左计算深度
while (left) {
left = left->left;
++leftDepth;
}
// 一路向右计算深度
while (right) {
right = right->right;
++rightDepth;
}
// 如果两边深度相同说明是满二叉树,根据公式计算节点数并返回
// 公式:节点数 = 2^leftDepth - 1
if (leftDepth == rightDepth) {
return (1 << leftDepth) - 1; // 左移运算符
}
int leftNum = getNum(cur->left); // 左
int rightNum = getNum(cur->right); // 右
int sum = leftNum + rightNum + 1; // 中,左右节点求和,加上自己一个节点
return sum;
}
int countNodes(TreeNode* root) {
return getNum(root);
}