快速求完全二叉树的节点个数
快速求完全二叉树的节点个数
作者:Grey
原文地址:
题目链接#
题目进阶要求
进阶:遍历树来统计节点是一种时间复杂度为
O(n)
的简单解决方案。你可以设计一个更快的算法吗?
暴力解法#
不考虑完全二叉树的这个性质,直接遍历一下二叉树,收集一下左右子树的节点个数,然后加上头节点,就是整个完全二叉树的节点个数,完整代码如下
public static int countNodes1(TreeNode head) {
if (head == null) {
return 0;
}
return p(head).all;
}
public static Info p(TreeNode head) {
if (head == null) {
return new Info(0);
}
Info leftInfo = p(head.left);
Info rightInfo = p(head.right);
// 收集左右子树节点个数加上头节点,就是整棵树的节点个数
int all = leftInfo.all + rightInfo.all + 1;
return new Info(all);
}
public static class Info {
public int all;
public Info(int a) {
all = a;
}
}
时间复杂度是O(N)
。
最优解#
需要利用一下完全二叉树的性质,首先,我们知道,树的高度,深度,层次有如下关系:
对于一棵完全二叉树,头节点一直往左滑直到叶子节点得到的层数一定是这个二叉树的最大层数,假设这个值为h
。
如果这个二叉树右树的最左节点的层数正好等于h
,说明这个二叉树左树一定是满二叉树
如果这个二叉树右树的最左节点的层数不等于h
,则说明这个二叉树的右树一定是满二叉树
由于满二叉树的节点个数可以通过树的高度计算出来:
public static int countNodes(TreeNode head) {
if (head == null) {
return 0;
}
int h = maxLenOfLeft(head, 1);
return count(head, 1, h);
}
private static int count(TreeNode head, int level, int h) {
if (level == h) {
return 1;
}
if (maxLenOfLeft(head.right, level + 1) == h) {
// 左树一定是满的
return (1 << (h - level)) + count(head.right, level + 1, h);
} else {
// 右数一定是满的,注意高度是 h - level - 1
return (1 << (h - level - 1)) + count(head.left, level + 1, h);
}
}
public static int maxLenOfLeft(TreeNode root, int level) {
while (root != null) {
root = root.left;
level++;
}
return level - 1;
}
通过如上方法,我们无须遍历整个二叉树,就可以把节点计算出来,复杂度低于O(N)
。
更多#
作者:GreyZeng
出处:https://www.cnblogs.com/greyzeng/p/16360786.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
你可以在这里自定义其他内容
本文来自博客园,作者:Grey Zeng,转载请注明原文链接:https://www.cnblogs.com/greyzeng/p/16360786.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程