算法练习第19天|222.完全二叉树的节点个数

222.完全二叉树的节点个数

222. 完全二叉树的节点个数 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/count-complete-tree-nodes/description/

题目描述:

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。题目数据保证输入的树是 完全二叉树

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例 1:

输入:root = [1,2,3,4,5,6]
输出:6

示例 2:

输入:root = []
输出:0

示例 3:

输入:root = [1]
输出:1

题目分析:

按照前文所讲的二叉树的递归遍历以及层序遍历,可以将完全二叉树看作普通二叉树处理,进行节点个数的统计。思路较为简单,代码如下:

后序递归遍历解法:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public://后序递归,第一步,确定函数参数以及返回值int countNodes(TreeNode* root) {      //递归第二步,确定递归终止条件。当递归函数指针root为空,递归终止if(root == nullptr) return 0;//递归第三步,确定单层递归逻辑:统计左右子树的节点个数,然后相加再加1int left = countNodes(root->left);  //左int right = countNodes(root->right);  //右int result = 1 + left + right;   //1就是后序遍历顺序的中           return result;}
};

层序遍历解法(也叫迭代法):

class Solution {
public://层序遍历int countNodes(TreeNode* root) {      if(root == nullptr) return 0;queue<TreeNode*> que;que.push(root);int result = 0;while(!que.empty()) {int size = que.size();for(int i = 0; i < size; i++){TreeNode * node = que.front();que.pop();result++;if(node->left)  que.push(node->left);if(node->right)  que.push(node->right);}}return result;}
};

 完全二叉树解法:

但是上述方法都是将完全二叉树当做普通二叉树来进行题目的求解,这样就忽略了完全二叉树的性质。完全二叉树时除了最底层的节点可能不满之外,其余层均是满的,并且,最底层的节点必须是严格从左往右依次排列的,不能有跳跃(如下面的最右侧的二叉树,蓝色框内存在跳跃,所以其不是完全二叉树)。

如果完全二叉树最底层也填满了的话,这时它就也是满二叉树。节点个数为2^{n} -1 ,n为二叉树的层数。

所以完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。

对于情况一,可以直接用2^{n} -1来计算。

对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。

关键点来了,怎么判断左右孩子是不是满二叉树?在完全二叉树中,如果递归一直向左遍历的深度等于递归一直向右遍历的深度,那说明就是满二叉树。前提是一定要在完全二叉树中。

所以,该解法的递归终止条件如下所示:

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,返回满足满二叉树的子树节点数量
}

递归三部曲,第三部,单层递归的逻辑:(可以看出使用后序遍历)

int leftTreeNum = countNodes(root->left);       // 左
int rightTreeNum = countNodes(root->right);     // 右
int result = leftTreeNum + rightTreeNum + 1;    // 中
return result;

 整体代码如下:

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;while(left)  //一直向左遍历,求深度{leftDepth++;left = left->left;}while(right) //一直向右遍历,求深度{rightDepth++;right = right->right;}if(leftDepth == rightDepth)  //当前的完全二叉树为满二叉树return (2 << leftDepth) - 1;  //2的n次方减一//递归第三步,确认单层递归逻辑//不然的话,就递归统计左右子树的节点数。每一级递归都会进行上面的满二叉树判断int left = countNodes(root->left);  //左int right = countNodes(root->right);  //右int result = left + right + 1;  //中return result;}
};

该解法与后续递归解法的不同之处就在于递归终止条件,该解法核心思想致力于逐子树判断是否为满二叉树。如果是,使用2^{n} -1计算节点数;如果不是,则进行下一层的递归countNodes。思路很巧妙。

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

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

相关文章

振动信号幅值成分分析手段

提示&#xff1a;振动信号幅值成分分析手段 文章目录 一、特征值分析二、概率密度分析2.1、原理2.2、代码2.3、结果分析 三、总结&#xff08;自己的思想&#xff09; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、特征值分析 均值和平均幅值可以…

【缓存常见问题】

在使用缓存时特别是在高并发场景下会遇到很多问题&#xff0c;常用的问题有缓存穿透、缓存击穿、缓存雪崩以及缓存一致性问题。 1、缓存穿透 首先&#xff0c;什么是缓存穿透呢&#xff1f; 缓存穿透是指请求一个不存在的数据&#xff0c;缓存层和数据库层都没有这个数据&…

虚拟天空解决方案,创造出令人惊叹的换天效果

在汽车视频领域&#xff0c;如何打破传统拍摄限制&#xff0c;呈现出更具创意和想象力的画面&#xff0c;成为众多企业和创作者追求的目标。美摄科技作为业界领先的视频技术提供商&#xff0c;凭借其强大的AI技术和三维渲染引擎&#xff0c;推出了全新的虚拟天空解决方案&#…

集成电路测试学习

集成电路&#xff08;Integrated Circuit&#xff0c;IC&#xff09;整个设计流程包括&#xff1a;电路设计、晶圆制造、晶圆测试、IC封装、封装后测试。 IC测试目的&#xff1a;一、确认芯片是否满足产品手册上定义的规范&#xff1b;二、通过测试测量&#xff0c;确认芯片可以…

李国武:QFD是如何将顾客需求转换为产品技术要求的?

如何将顾客的多样化需求精准地转化为产品的技术要求&#xff0c;成为企业赢得市场、提升竞争力的关键。质量功能展开&#xff08;Quality Function Deployment&#xff0c;简称QFD&#xff09;作为一种先进的质量管理工具&#xff0c;正是实现这一转换的有效桥梁。具体如天行健…

vim相关指令

vim的各种模式及其转换关系图 vim 默认处于命令模式&#xff01;&#xff01;&#xff01; 模式之间转换的指令 除【命令模式】之外&#xff0c;其它模式要切换到【命令模式】&#xff0c;只需要无脑 ESC 即可&#xff01;&#xff01;&#xff01; [ 命令模式 ] 切换至 [ 插…

unity动画的关键帧添加event-同步语音

在iclone中做的语音嘴型动画&#xff0c;因是用下图自带的方式语音生成的动画&#xff0c;而不是用plugin(面捕live会连同语音一起导出)&#xff0c;所以导出来到Unity中&#xff0c;之后口型、动作、表情等没有声音。 我需要把原有的语音也重新在unity中加载上&#xff0c;原来…

解决WPS右键菜单冗余选项,去除WPS右键菜单选项

问题描述 安装WPS后&#xff0c;右键菜单会多出许多无用的选项&#xff0c;如何去除&#xff1f; 解决方法 按下WindowsS打开搜索栏&#xff0c;搜索配置工具打开 勾选所有的关闭和隐藏选项

汽车视频智能剪辑解决方案,满足用户对高品质汽车视频的追求

随着汽车智能化和互联网技术的快速发展&#xff0c;车载视频已经成为现代驾驶生活不可或缺的一部分。然而面对海量的行车视频&#xff0c;如何高效地剪辑、整理并分享这些精彩瞬间&#xff0c;一直是车主和汽车内容创作者们所面临的难题。美摄科技&#xff0c;作为领先的视频智…

Postgres数据库中的死锁是如何产生的,如何避免和解决?

文章目录 死锁的产生原因如何避免死锁如何解决死锁示例代码查询死锁信息终止事务 在Postgres数据库中&#xff0c;死锁是一种特殊的情况&#xff0c;其中两个或多个事务相互等待对方释放资源&#xff0c;从而导致它们都无法继续执行。这种情况通常发生在多个事务尝试以不同的顺…

SQL255 给出employees表中排名为奇数行的first_name

题目来源&#xff1a; 给出employees表中排名为奇数行的first_name_牛客题霸_牛客网 描述 对于employees表中&#xff0c;输出first_name排名(按first_name升序排序)为奇数的first_name CREATE TABLE employees ( emp_no int(11) NOT NULL, birth_date date NOT NULL, firs…

高德地图API-鼠标点击地图获取经纬度坐标(关键操作)

效果图&#xff1a; 有了经纬度坐标&#xff0c;就可以得到城市的&#xff1a;adcode区域编码 html版本 <!doctype html> <html> <head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge"&g…

Unity类银河恶魔城学习记录13-1 p142 Save system源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili FileDataHandler.cs using System; using System.IO; using UnityEngine; p…

数据结构学习记录

数据结构 数组 & 链表 相连性 | 指向性 数组可以迅速定位到数组中某一个节点的位置 链表则需要通过前一个元素指向下一个元素&#xff0c;需要前后依赖顺序查找&#xff0c;效率较低 实现链表 // head > node1 > node2 > ... > nullclass Node {constructo…

基于springboot+vue+Mysql的社区维修平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

软件产品许可证书 Licence 全流程研发(使用非对称加密技术,既安全又简单)

本篇博客对应的代码地址&#xff1a; Gitee 仓库地址&#xff1a;https://gitee.com/biandanLoveyou/licence 源代码百度网盘链接: https://pan.baidu.com/s/1_ZhdcENcrk2ZuL11hWDLTQ?pwdbmxi 提取码: bmxi 1、背景介绍 公司是做软件 SAAS 服务的&#xff0c;一般来说软件部…

RabbitMQ项目实战(一)

文章目录 RabbitMQ项目实战选择客户端基础实战 前情提要&#xff1a;我们了解了消息队列&#xff0c;RabbitMQ的入门&#xff0c;交换机&#xff0c;以及核心特性等知识&#xff0c;现在终于来到了激动人心的项目实战环节&#xff01;本小节主要介绍通过Spring Boot RabbitMQ S…

2021年全国大学生电子设计竞赛D题——基于互联网的摄像测量系统(三)

13 测试方案和测量结果 测量一个边长为1米的正方形&#xff0c;取三个顶点分别作为O、A、B点。 在O点上方&#xff0c;用细线悬挂激光笔&#xff0c;激光笔常亮向下指示&#xff0c;静止时激光笔的光点和O点重合。 将两个D8M摄像头子卡插到DE10-Nano开发板上&#xff0c;放…

MySQL Linux环境安装部署

目录 1、mysql安装包下载 2、安装mysql服务 3、启动mysql服务 4、登录mysql服务 1、mysql安装包下载 1、查看centos的版本 cat /etc/redhat-release 2、进入官网地址下载对应系统版本的安装包 地址&#xff1a;MySQL :: Download MySQL Yum Repository 2、安装mysql服务 …

恒峰智慧科技-森林消防便捷泵:轻松应对火灾危机!

在广袤无垠的森林中&#xff0c;绿色是生命的象征&#xff0c;是自然的馈赠。然而&#xff0c;当火魔无情地吞噬这片生命的绿洲时&#xff0c;我们需要一种快速、高效、可靠的消防工具来守护这片绿色。此时&#xff0c;森林消防便捷泵应运而生&#xff0c;成为了守护森林安全的…