104. 二叉树的最大深度
题目
题解
后序遍历
class Solution {
public:
int depth(TreeNode* left,TreeNode*right,int depthCount)
{
if(right == NULL && left == NULL)
return 0 + depthCount ;
else if(right == NULL && left != NULL)
return depth(left->left,left->right,depthCount) + depthCount + 1;
else if(right != NULL && left == NULL)
return depth(right->left,right->right,depthCount) + depthCount + 1;
else
{
int leftDepth = depth(left->left,left->right,depthCount);
int rightDepth = depth(right->left,right->right,depthCount);
return max(leftDepth , rightDepth) + depthCount + 1;
}
}
int maxDepth(TreeNode* root) {
if(root == NULL)
return 0;
return depth(root->left,root->right,0) + 1;//传入迭代的是根节点的子节点,因此返回值也是子节点的深度,根节点需要+1
}
};
better:
class solution {
public:
int getdepth(treenode* node) {
if (node == NULL) return 0;
int leftdepth = getdepth(node->left); // 左
int rightdepth = getdepth(node->right); // 右
int depth = 1 + max(leftdepth, rightdepth); // 中
return depth;
}
int maxdepth(treenode* root) {
return getdepth(root);
}
};
注意(后序遍历)
1.高度:叶子节点到该节点的路径上的节点数(后序遍历-左右中-先计算左右子节点的高度再计算父节点高度)
深度:根节点该叶子节点的路径上的节点数(前序遍历-中左右-先计算父节点深度再计算左右子节点深度)
根节点的高度就是二叉树的最大深度
2.每到一个中节点就要+1
111. 二叉树的最小深度
题目
题解
后序遍历
class Solution {
public:
int depth(TreeNode* left,TreeNode*right,int depthCount)
{
if(right == NULL && left == NULL)
return 0 + depthCount ;
else if(right == NULL && left != NULL)
return depth(left->left,left->right,depthCount) + depthCount + 1;
else if(right != NULL && left == NULL)
return depth(right->left,right->right,depthCount) + depthCount + 1;
else
{
int leftDepth = depth(left->left,left->right,depthCount);
int rightDepth = depth(right->left,right->right,depthCount);
return min(leftDepth , rightDepth) + depthCount + 1;
}
}
int minDepth(TreeNode* root) {
if(root == NULL)
return 0;
return depth(root->left,root->right,0) + 1;
}
};
注意
针对图中的情况,按照 104. 二叉树的最大深度的better解法(max(leftdepth, rightdepth)改为min(leftdepth, rightdepth)),会导致计算结果为0,与题意不符
222. 完全二叉树的节点个数
题目
题解
后序遍历
class Solution {
public:
int count(TreeNode* node)
{
if(node == NULL) return 0;
int left = count(node->left);
int right = count(node->right);
return left + right + 1;
}
int countNodes(TreeNode* root) {
if(root == NULL) return 0;
return count(root);
}
};
层序遍历
class Solution {
public:
int countNodes(TreeNode* root) {
if(root == NULL) return 0;
int count = 0;
queue<TreeNode*> que;
que.push(root);
while(!que.empty())
{
int size = que.size();
while(size--)
{
TreeNode* node = que.front();
que.pop();
count++;
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return count;
}
};
借助完全二叉树特性
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;
}
};
注意
1.左移n位表示乘以2的n次方,2左移n位表示2乘以2的n次方,即表示乘以2的(n + 1)次方
2.通过比较左节点数和右节点数可以判断是否为完全二叉树