目录
- 前言
- 题目
- 1.利用完全二叉树性质的递归
- 2. 本题思路分析:
- 3. 算法实现
- 4. pop函数的算法复杂度
- 5. 算法坑点
前言
在本科毕设结束后,我开始刷卡哥的“代码随想录”,每天一节。自己的总结笔记均会放在“算法刷题-代码随想录”该专栏下。
代码随想录此题链接
题目
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
1.利用完全二叉树性质的递归
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。
对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。
2. 本题思路分析:
本题使用递归,并且利用二叉树性质
这里关键在于如何去判断一个左子树或者右子树是不是满二叉树呢?
在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。如图:
在完全二叉树中,如果递归向左遍历的深度不等于递归向右遍历的深度,则说明不是满二叉树,如图:
3. 算法实现
- 代码:
//针对完全二叉树的解法
public int countNodes(TreeNode root) {
//完全二叉树解法
//主要是 利用了 计算满二叉树节点数为:2^n - 1 (n为层数,根节点为第一层)
if(root == null) return 0;
int leftDepth = 1,rightDepth = 1;
TreeNode cur = root;
while(cur.left != null){
leftDepth++;
cur = cur.left;
}
cur = root;
while(cur.right != null){
rightDepth++;
cur = cur.right;
}
if(rightDepth == leftDepth){
return (int)Math.pow(2,rightDepth) - 1;
}
return countNodes(root.left) + countNodes(root.right) + 1;
}
层序迭代:
public int countNodes(TreeNode root) {
if(root == null){
return 0;
}
Deque<TreeNode> queue = new ArrayDeque();
queue.offer(root);
int sum = 0;
while(!queue.isEmpty()){
int size = queue.size();
for(int i = 0;i < size;i++){
TreeNode cur = queue.poll();
sum++;
if(cur.left != null){
queue.offer(cur.left);
}
if(cur.right != null){
queue.offer(cur.right);
}
}
}
return sum;
}
4. pop函数的算法复杂度
n为总结点数
时间复杂度:O(log n × log n)
空间复杂度:O(log n)
5. 算法坑点
暂无