93、【树与二叉树】leetcode ——222. 完全二叉树的节点个数:普通二叉树求法+完全二叉树性质求法(C++版本)

news2024/11/23 13:27:56

题目描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原题链接:222. 完全二叉树的节点个数

解题思路

1、普通二叉树节点个数求法

(1)迭代:层序遍历BFS

遍历一层获取一层结点

/**
 * 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) {
        if(!root)       return 0;
        int res = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(!que.empty()) {
            int n = que.size();
            while(n--) {
                TreeNode* node = que.front();
                que.pop();
                res++;
                if(node->left)      que.push(node->left);
                if(node->right)     que.push(node->right);
            }
        }
        return res;
    }
};

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( n ) O(n) O(n)

(2)递归:先序遍历DFS

/**
 * 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 nums = 0;
    int countNodes(TreeNode* root) {
        if(!root)       return 0;
        nums++;                             // 中:每遍历一个非空结点,加一
        if(!root->left && !root->right)     return 1;    // 刚开始遍历时,树中若只有一个结点,则返回1
        countNodes(root->left);             // 左
        countNodes(root->right);            // 右
        return nums;    // 最后从栈一个弹出的函数,有nums的最终值
    }
};

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( l o g n ) O(log n) O(logn) (不考虑系统栈)

(3)迭代:后序遍历(子问题分解)

/**
 * 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) {
        if(!root)       return 0;
        int leftcnt = countNodes(root->left);       // 左
        int rightcnt = countNodes(root->right);     // 右
        return leftcnt + rightcnt + 1;              // 中:将结果返回给上一层
    }
};

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( l o g n ) O(log n) O(logn) (不考虑系统栈)

2、完全二叉树性质求节点个数

image.png
满二叉树的特点:左子树左侧边的高度=右子树右侧边的高度,节点个数= 2 n − 1 2^n-1 2n1
完全二叉树的特点:除了最后一层外,其余层全部为满二叉树。

可以将这个问题分解成子问题,求根节点所拥有的左右子树节点个的结点个数,最后得到整棵树的总个数。而每遍历到一颗子树时,可以利用满二叉树的特点查看该子树是否为一颗满二叉树,若为满二叉树,直接根据节点个数公式返回即可若为不满二叉树,则算上该节点(总结点个数加一),然后再向下递归计算其左右子树结点个数

/**
 * 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 level = 0;
    int countNodes(TreeNode* root) {
        if(!root)       return 0;        
        // 先求左子树左侧高度和右子树右侧高度
        TreeNode* leftnode = root->left;
        TreeNode* rightnode = root->right;
        int leftLevel = 0, rightLevel = 0;      // 2左移从0开始,1左移从1开始
        while(leftnode) {
            leftLevel++;
            leftnode = leftnode->left;            
        }
        while(rightnode) {
            rightLevel++;
            rightnode = rightnode->right;
        }
        // 若为满二叉树,左子树左侧高度应该等于右子树右侧高度
        if(leftLevel == rightLevel)      return (1 << leftLevel) - 1;       // 2<<0 = 2 , 2<<n = 2^(n+1),因此规定从0开始
        // 若不为满二叉树,则算此结点个数,并求再求左右子树的结点个数
        return countNodes(root->left) + countNodes(root->right) + 1;
    }
};

时间复杂度 O ( l o g 2 n ) O(log^2 n) O(log2n)
空间复杂度 O ( l o g n ) O(log n) O(logn)

注: 0 < n ≤ 4 0<n≤4 0<n4时, O ( n ) ≥ O ( l o g 2 n ) O(n) ≥ O(log^2 n) O(n)O(log2n);当 n ≥ 5 n≥5 n5时, O ( n ) < O ( l o g 2 n ) O(n) < O(log^2 n) O(n)O(log2n)

参考文章:222.完全二叉树的节点个数、如何计算完全二叉树的节点数

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

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

相关文章

【九】Netty HTTP+XML协议栈开发

HTTP协议介绍业务场景流程图技术栈设计流程图的分析:Step 1Step2Step3Step4Step5分析结果开发开发流程图代码jar 依赖代码结构如图pojo 包request包response 包client 包server包编码解码基类代码说明测试服务端打印结果客户端打印结果总结介绍 由于HTTP协议的通用性&#xff…

使用js实现一个可以【放烟花】的小游戏

放烟花游戏需求&#x1f447;核心玩法&#x1f447;&#x1f447;界面原型&#x1f447;&#x1f447;成品演示&#x1f447;游戏开发1.游戏素材准备2.代码实现1.创建index.html页面2.首页-开始3.加载烟花音效4.重玩儿放烟花的小游戏。点击页面放烟花。兼容移动端。 游戏需求 …

作为普通网民,这些“实用电脑神器”,值得你知道

国内软件夹缝里求生存&#xff0c;由于某些不良软件&#xff0c;许多人对于国产软件认识多为“流氓、捆绑、多广告”&#xff0c;其实并非如此&#xff0c;下面几款让你刮目相看&#xff0c;扭转观念。 1、图片视频画质增强器 这是一款功能极其强大的图片与视频画质增强器&…

阿里云数据湖3.0解决方案两度登上InfoQ 2022年度榜单

经过一个多月的层层竞选&#xff0c;【阿里云数据湖 3.0 解决方案】从 130 多个方案中脱颖而出&#xff0c;荣获 InfoQ 2022 年度中国技术力量年度榜单《十大云原生创新技术方案》&《云原生十大场景化落地方案》双料大奖&#xff0c;这是头部技术媒体对阿里云存储的再一次认…

低代码是什么?有什么优势?一文看懂LowCode

低代码到底是什么&#xff1f;用最简单的方式告诉我&#xff1f;低代码是近两年来一个很热门的概念&#xff0c;尤其是疫情的影响&#xff0c;市场对低代码的需求不断增加&#xff0c;但到底什么是低代码&#xff1f;它到底有什么好处&#xff1f;这篇就为大家解答这个问题&…

vue2.0 插槽不是响应性的

请注意插槽不是响应性的。如果你需要一个组件可以在被传入的数据发生变化时重渲染&#xff0c;我们建议改变策略&#xff0c;依赖诸如 props 或 data 等响应性实例选项。-- vm.$slots 问题描述 项目中自定了组件 widget&#xff0c;作为容器&#xff0c;其中 header 部分做了预…

SCI投稿:MDPI旗下期刊Mathematics投稿经历

最近写了篇论文&#xff0c;由于国内期刊现状&#xff08;懂的都懂&#xff09;&#xff0c;打算投国外的期刊&#xff0c;看来看去选择投MDPI旗下的Mathematics。手稿经过一轮大修之后顺利收到了Accepted&#xff0c;过程还是比较顺利的&#xff0c;记录一下投稿过程。 论文撰…

Matlab实现的FEMIC的说明书

FEMIC程序是用来反演小回路频域电磁感应数据的。要启动代码,在Matlab命令窗口中输入start,然后点击“Enter”或“返回”按钮。然后会出现FEMIC的主界面,见图1。 它由几个输入区域组成,这几个区分别实现了:加载数据,反演过程控制和最终显示。 图1 主界面 下面对这些输入…

[oeasy]python0045_四种进制_binary_octal_decimal_hexadecimal

四种进制 回忆上次内容 上次研究了 通过 八进制数值 转义 \ooo把(ooo)8进制对应的ascii字符输出 转义序列 \n、\t 是 转义序列\xhh 也是 转义序列\ooo 还是 转义序列 现在 总共有 几种进制 了呢&#xff1f;&#x1f914; 先数一下 树 数树 树 就是这么多棵树 用八进制的…

Redis持久化Redis主从

Redis持久化 RDB持久化 RDB: Redis数据备份文件。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文件&#xff0c;恢复数据。 主要流程 bgsave开始时会fork主进程得到子进程&#xff0c;子进程共享主进程的内存数据。完成f…

误删的文件不在回收站如何找回?分享一些恢复数据的教程

电脑清理的文件数据&#xff0c;一般都会经过回收站。如果想要恢复回来&#xff0c;可以直接打开电脑的回收站来寻找。可凡事都有万一&#xff0c;我们删除的文件不在回收站里面。这是什么原因&#xff1f;误删的文件不在回收站如何找回&#xff1f;今天就来分享如何恢复不在回…

git快速学习笔记

1.目标 了解Git基本概念能够概述git工作流程能够使用Git常用命令熟悉Git代码托管服务能够使用idea操作git 2.概述 2.1开发中的实际场景 场景一&#xff1a;备份 小明负责的模块就要完成了&#xff0c;就在即将Release之前的一瞬间&#xff0c;电脑突然蓝屏&#xff0c;硬盘光…

C语言进阶(6)——结构体

文章目录1.结构体的基础知识2.结构体的声明3.特殊的声明4.结构体的自引用6. 结构体的内存对齐7.修改默认对齐数8.结构体传参位段1、位段定义2. 位段的内存分配3.位段的跨平台问题4.位段的运用场景1.结构体的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的…

51单片机——LED基础

从小就对电器元件比较感兴趣吧&#xff0c;经常拿坏的电器里面的芯片拆下来玩&#xff0c;甚至那些没坏的电器&#xff0c;比如我家的电视&#xff0c;也会希望它能坏掉&#xff0c;我好去看看里面是什么样子的&#xff0c;为什么能播放节目……&#xff0c;所以我第一眼看到51…

阿里云-解决EDAS创建应用文件过大无法上传部署问题

文章目录1、背景2、问题具体描述3、解决方案3.1、 2种方案3.2 、OSS 简介3.3、 OSS 功能特性4、 OSS 实操4.1、 上传程序文件4.2、 创建应用1、背景 在一次使用阿里云-EDAS发布应用服务过程中出现EDAS 上传应用包过大无法上传现象。 2、问题具体描述 最近在使用阿里云-EDAS发…

1.1.2续 特殊二极管部分选型

目录 1.稳压管 2.发光二极管 4.光电二极管 5.整流二极管 1.稳压管 利用二极管的反向击穿特性制成的&#xff0c;在电路中其两端的电压保持基本不变&#xff0c;起到稳定电压的作用 Vz 稳定电压&#xff1a;反向击穿后稳定工作的电压 Iz 稳定电流&#xff1a;工作电压等于…

Java异常情况了解

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主 专栏&#xff1a;JavaSE 作者介绍&#xff1a;大三学生&#xff0c;希望一起进步~ 文章目录 目录 文章目录 一、异常结构体系 二、异常分类 三、异常处理 3.1异常抛出 3.2 异常捕获 四.【面试题】 五、题目练习…

大数据必学Java基础(一百一十九):Maven仓库与JDK的配置

文章目录 Maven仓库与JDK的配置 一、Maven仓库 二、JDK的配置 Maven仓库与JDK的配置 一、Maven仓库 Maven仓库是基于简单文件系统存储的,集中化管理Java API资源(构件)的一个服务。 仓库中的任何一个构件都有其唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路…

Linux:gcc工具

文章目录一.程序的翻译二.gcc工具的使用2.1gcc 文件名(直接编译)2.2gcc -o 自定义 原文件(自定义生成可执行程序名称)2.3./可执行文件2.4gcc -E(程序运行到预处理后结束)2.5gcc -S(程序运行到编译之后结束)2.6gcc -i(程序运行到汇编之后结束)2.7小结三.链接的过程3.1ldd命令3.2…

2023年最新谷歌Google帐号Gmail邮箱账号怎么注册成功的方法与教程?

因为工作、游戏或其他需求&#xff0c;有时需要使用谷歌Google帐号或Gmail邮箱账号。首先明确&#xff1a;谷歌google帐号不一定是Gmail邮箱帐号&#xff0c;但是Gmail邮箱账号一定是谷歌帐号。所以&#xff0c;大家注册Google谷歌帐号时默认为谷歌Gmail邮箱帐号就可以满足谷歌…