【leetcode练习·二叉树】计算完全二叉树的节点数

本文参考labuladong算法笔记[拓展:如何计算完全二叉树的节点数 | labuladong 的算法笔记]

如果让你数一下一棵普通二叉树有多少个节点,这很简单,只要在二叉树的遍历框架上加一点代码就行了。

但是,力扣第第 222 题「完全二叉树的节点个数」给你一棵完全二叉树,让你计算它的节点个数,你会不会?算法的时间复杂度是多少?

这个算法的时间复杂度应该是 O(logN∗logN)O(logN∗logN),如果你心中的算法没有达到这么高效,那么本文就是给你写的。

关于「完全二叉树」和「满二叉树」等名词的定义,可以参考基础知识章节的 二叉树基础。

一、思路分析

现在回归正题,如何求一棵完全二叉树的节点个数呢?

# 输入一棵完全二叉树,返回节点总数
def countNodes(root: TreeNode) -> int:

如果是一个普通二叉树,显然只要向下面这样遍历一边即可,时间复杂度 O(N)O(N):

def countNodes(root: TreeNode) -> int:if root == None:return 0return 1 + countNodes(root.left) + countNodes(root.right)

那如果是一棵二叉树,节点总数就和树的高度呈指数关系:

def countNodes(root: TreeNode) -> int:h = 0# 计算树的高度while root:root = root.lefth += 1# 节点总数就是 2^h - 1return 2 ** h - 1

完全二叉树比普通二叉树特殊,但又没有满二叉树那么特殊,计算它的节点总数,可以说是普通二叉树和完全二叉树的结合版,先看代码:

class Solution:def countNodes(self, root: TreeNode) -> int:l = rootr = roothl = 0hr = 0# 沿最左侧和最右侧分别计算高度while l is not None:l = l.lefthl += 1while r is not None:r = r.righthr += 1# 如果左右侧计算的高度相同,则是一棵满二叉树if hl == hr:return pow(2, hl) - 1# 如果左右侧的高度不同,则按照普通二叉树的逻辑计算return 1 + self.countNodes(root.left) + self.countNodes(root.right)

结合刚才针对满二叉树和普通二叉树的算法,上面这段代码应该不难理解,就是一个结合版,但是其中降低时间复杂度的技巧是非常微妙的

二、复杂度分析

开头说了,这个算法的时间复杂度是 O(log⁡N×log⁡N)O(logN×logN),这是怎么算出来的呢?

直觉感觉好像最坏情况下是 O(N×log⁡N)O(N×logN) 吧,因为之前的 while 需要 log⁡NlogN 的时间,最后要 O(N)O(N) 的时间向左右子树递归:

return 1 + countNodes(root.left) + countNodes(root.right);

关键点在于,这两个递归只有一个会真的递归下去,另一个一定会触发 hl == hr 而立即返回,不会递归下去

为什么呢?原因如下:

一棵完全二叉树的两棵子树,至少有一棵是满二叉树

看图就明显了吧,由于完全二叉树的性质,其子树一定有一棵是满的,所以一定会触发 hl == hr,只消耗 O(log⁡N)O(logN) 的复杂度而不会继续递归。

综上,算法的递归深度就是树的高度 O(log⁡N)O(logN),每次递归所花费的时间就是 while 循环,需要 O(log⁡N)O(logN),所以总体的时间复杂度是 O(log⁡N×log⁡N)O(logN×logN)。

所以说,「完全二叉树」这个概念还是有它存在的原因的,不仅适用于数组实现二叉堆,而且连计算节点总数这种看起来简单的操作都有高效的算法实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/10657.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

低代码系统-产品架构案例介绍、轻流(九)

轻流低代码产品定位为零代码产品,试图通过搭建来降低企业成本,提升业务上线效率。 依旧是从下至上,从左至右的顺序 名词概述运维层底层系统运维层,例如上线、部署等基础服务体系内置的系统能力,发消息、组织和权限是必…

对顾客行为的数据分析:融入2+1链动模式、AI智能名片与S2B2C商城小程序的新视角

摘要:随着互联网技术的飞速发展,企业与顾客之间的交互方式变得日益多样化,移动设备、社交媒体、门店、电子商务网站等交互点应运而生。这些交互点不仅为顾客提供了便捷的服务体验,同时也为企业积累了大量的顾客行为数据。本文旨在…

MSA Transformer

过去的蛋白质语言模型以单个序列为输入,MSA Transformer以多序列比对的形式将一组序列作为输入。该模型将行和列注意力交织在输入序列中,并在许多蛋白质家族中使用mask语言建模目标进行训练。模型的性能远超过了当时最先进的无监督学习方法,其…

QT实现有限元软件操作界面

本系列文章致力于实现“手搓有限元,干翻Ansys的目标”,基本框架为前端显示使用QT实现交互,后端计算采用Visual Studio C。 本篇将二维矩形截面梁单元(Rect_Beam2D2Node)组成的钢结构桥作为案例来展示软件功能。 也可以…

推荐一款好用的翻译类浏览器扩展插件

给大家推荐一款实用的翻译工具——沉浸式翻译。这是一款免费、高效的AI驱动浏览器扩展插件,能够帮助用户轻松打破语言障碍,享受沉浸式的阅读体验。 主要特性 沉浸式阅读体验:通过智能识别网页主内容区域并进行双语对照翻译,让用户…

ElasticSearch-文档元数据乐观并发控制

文章目录 什么是文档?文档元数据文档的部分更新Update 乐观并发控制 最近日常工作开发过程中使用到了 ES,最近在检索资料的时候翻阅到了 ES 的官方文档,里面对 ES 的基础与案例进行了通俗易懂的解释,读下来也有不少收获&#xff0…

开源的瓷砖式图像板系统Pinry

简介 什么是 Pinry ? Pinry 是一个开源的瓷砖式图像板系统,旨在帮助用户轻松保存、标记和分享图像、视频和网页。它提供了一种便于快速浏览的格式,适合喜欢整理和分享多种媒体内容的人。 主要特点 图像抓取和在线预览:支持从网页…

Java 大视界 -- Java 大数据在自动驾驶中的数据处理与决策支持(68)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

【数据结构】初识链表

顺序表的优缺点 缺点: 中间/头部的插入删除,时间复杂度效率较低,为O(N) 空间不够的时候需要扩容。 如果是异地扩容,增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗。 扩容可能会存在…

I.MX6ULL 中断介绍上

i.MX6ULL是NXP(原Freescale)推出的一款基于ARM Cortex-A7内核的微处理器,广泛应用于嵌入式系统。在i.MX6ULL中,中断(Interrupt)是一种重要的机制,用于处理外部或内部事件,允许微处理…

4-图像梯度计算

文章目录 4.图像梯度计算(1)Sobel算子(2)梯度计算方法(3)Scharr与Laplacian算子4.图像梯度计算 (1)Sobel算子 图像梯度-Sobel算子 Sobel算子是一种经典的图像边缘检测算子,广泛应用于图像处理和计算机视觉领域。以下是关于Sobel算子的详细介绍: 基本原理 Sobel算子…

苍穹外卖——数据统计

在商家管理端的左侧,有一个名为"数据统计"的菜单,该页面负责展示各个维度的数据统计,分别是营业额统计、用户统计、订单统计、销量排名top10。统计的数据是借助一些图形化的报表技术来生成并展示的。在左上角还可选择时间段&#x…

优盘恢复原始容量工具

买到一个优盘,显示32mb,我见过扩容盘,但是这次见到的是缩容盘,把2g的容量缩成32MB了,首次见到。。用芯片查询工具显示如下 ChipsBank(芯邦) CBM2199E 使用以下工具,恢复原始容量。。 其他CMB工具可能不行…

Flutter Candies 一桶天下

| | | | | | | | 入魔的冬瓜 最近刚入桶的兄弟,有责任心的开发者,对自己的项目会不断进行优化,达到最完美的状态 自定义日历组件 主要功能 支持公历,农历,节气,传统节日,常用节假日 …

[Collection与数据结构] B树与B+树

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

ROS应用之SwarmSim在ROS 中的协同路径规划

SwarmSim 在 ROS 中的协同路径规划 前言 在多机器人系统(Multi-Robot Systems, MRS)中,SwarmSim 是一个常用的模拟工具,可以对多机器人进行仿真以实现复杂任务的协同。除了任务分配逻辑以外,SwarmSim 在协同路径规划方…

新鲜速递:DeepSeek-R1开源大模型本地部署实战—Ollama + MaxKB 搭建RAG检索增强生成应用

在AI技术快速发展的今天,开源大模型的本地化部署正在成为开发者们的热门实践方向。最火的莫过于吊打OpenAI过亿成本的纯国产DeepSeek开源大模型,就在刚刚,凭一己之力让英伟达大跌18%,纳斯达克大跌3.7%,足足是给中国AI产…

【Rust自学】15.5. Rc<T>:引用计数智能指针与共享所有权

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 15.5.1. 什么是Rc<T> 所有权在大部分情况下都是清晰的。对于一个给定的值&#xff0c;程序员可以准确地推断出哪个变量拥有它。 …

UE5制作视差图

双目深度估计开源数据集很多都是用UE制作的&#xff0c;那么我们自己能否通过UE制作自己想要的场景的数据集呢。最近花了点时间研究了一下&#xff0c;分享给需要的小伙伴。 主要使用的是UnrealCV插件&#xff0c;UnrealCV是一个开源项目&#xff0c;旨在帮助计算机视觉研究人…

基于遗传优化GRNN和Hog特征提取的交通标志识别算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 HOG 4.2 GRNN&#xff08;General Regression Neural Network&#xff09;模型原理 4.3 遗传算法&#xff08;GA&#xff09;优化GRNN平滑因子 5.算法完整程序工程 1.算法运行效果图预…