目录结构
1.题目
给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 个节点。
示例:
输入:
1
/ \
2 3
/ \ /
4 5 6
输出: 6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.题解
2.1递归计数
public class Solution222 {
@Test
public void test222() {
TreeNode root = new TreeNode(1, new TreeNode(2, new TreeNode(4), new TreeNode(5)),
new TreeNode(3, new TreeNode(6), null));
System.out.println(countNodes(root));
}
public int countNodes(TreeNode root) {
if (root != null) {
return countNodes(root.left) + countNodes(root.right) + 1;
}
return 0;
}
}
- 时间复杂度:,每个节点遍历一次。
- 空间复杂度:,题设给定为完全二叉树,故递归深度为树高度。
2.2二分查找+位运算
根据题设,根节点为第0层,完全二叉树的最大层数为h。
由完全二叉树的性质:
- 最左边的节点一定位于最底层,故从根节点出发,不断访问左子树,直到遇到叶节点,该叶节点即为完全二叉树的最左边的节点,经过的路径长度即为最大层数h;
- 对于第层(),有个节点;
- 对于第层,包含的节点个数最少为1,最多为;
- 前层包含节点个数。
故对于最大层数为 h的完全二叉树,节点个数一定在的范围内,可在该范围内通过二分查找的方式得到完全二叉树的节点个数:
- 通过上述性质1获取最大层数h;
- 根据h可由上述性质3得到第h层个数的区间,将其由0开始编号,故编号范围是(原因见下面判断编号k是否存在);
- 在中由二分查找法搜索存在的最大编号k(若节点k存在,则最底层节点个数一定≥k+1,若节点k不存在,则最底层节点个数一定<k+1);
- 最后返回。
判断编号k是否存在:
- 若将父节点与左子节点之间的边用0表示,父节点与右子节点之间的边用1表示,则最底层节点的编号的二进制从高位到低位正好表示了根节点到该节点的路径,故可由此判断是否存在;
- 这样正是将最底层从0编号的原因。
public class Solution222 {
@Test
public void test222() {
TreeNode root = new TreeNode(1, new TreeNode(2, new TreeNode(4), new TreeNode(5)),
new TreeNode(3, new TreeNode(6), null));
System.out.println(countNodes(root));
}
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
int level = 0;
TreeNode tmp = root;
while (tmp.left != null) {
level++;
tmp = tmp.left;
}
int left = 0, right = (1 << level) - 1, bits = 1 << (level - 1);
while (left < right) {
int mid = (right - left + 1) / 2 + left;
if (judge(root, bits, mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return (int) (Math.pow(2, level)) + left;
}
public boolean judge(TreeNode root, int bits, int k) {
while (root != null && bits > 0) {
if ((bits & k) == 0) {
root = root.left;
} else {
root = root.right;
}
bits >>= 1;
}
return root != null;
}
}
- 时间复杂度:,获取最大层数,对最底层h的节点进行二分查找次,且每个判断是否存在需要。
- 空间复杂度:。