leetocde662. 二叉树最大宽度,面试必刷题,思路清晰,分点解析,附代码详解带你完全弄懂

leetocde662. 二叉树最大宽度

做此题之前可以先做一下二叉树的层序遍历。具体题目如下:

leetcode102二叉树的层序遍历

我也写过题解,可以先看看学习一下,如果会做层序遍历了,那么这题相对来说会简单很多。

具体题目

给你一棵二叉树的根节点 root ,返回树的 最大宽度

树的 最大宽度 是所有层中最大的 宽度

每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。

题目数据保证答案将会在 32 位 带符号整数范围内。

示例 1:
在这里插入图片描述
输入:root = [1,3,2,5,3,null,9]
输出:4
解释:最大宽度出现在树的第 3 层,宽度为 4 (5,3,null,9) 。

示例 2:
在这里插入图片描述
输入:root = [1,3,2,5,null,null,9,6,null,7]
输出:7
解释:最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7)

示例 3:
在这里插入图片描述
输入:root = [1,3,2,5]
输出:2
解释:最大宽度出现在树的第 2 层,宽度为 2 (3,2) 。

1.预分析

核心思想还是使用广度优先搜索(BFS)来遍历二叉树的每一层。
但这题不一样的是,它必须多保存一个数据,即二叉树的节点位置。

节点位置编号的重要性
在二叉树的层序遍历中,通常只需要访问每个节点一次。然而,为了计算宽度,即树的层间最大节点数,我们还需要知道每个节点在层中的位置。这就需要为每个节点分配一个唯一的位置编号,以反映其在层中的相对位置。

完全二叉树的位置编号策略
在完全二叉树中,每个节点的位置可以通过其在层中的索引来表示。对于任意节点,其左子节点的索引是当前节点索引的2倍,右子节点的索引是当前节点索引的2倍加1。这种索引策略允许我们快速地为子节点分配新的位置编号,而不需要额外的计算。

pair数据结构
由于既要保存二叉树节点,又要保存二叉树的位置,所以我们需要pair数据结构同时保存两个数据。

pair 是一个在 C++ 标准库中定义的模板类,用于存储两个元素的组合。它通常用于需要同时存储两个相关数据的场景
访问元素:pair 提供了 first 和 second 两个成员变量,分别用于存储和访问第一个和第二个元素。例如,pair<int, double> p(3, 4.5); 创建了一个 pair 对象 p,其中 p.first 是整数3,p.second 是浮点数4.5。

2.算法思路分析

输入检查:首先检查传入的二叉树根节点 root 是否为 nullptr。如果是,说明二叉树为空,其宽度为0,直接返回。

初始化变量:定义一个 unsigned long long 类型的变量 maxWidth 用于存储遍历过程中计算出的最大宽度。同时,定义一个队列 q,用于存储当前层的节点以及它们的位置编号。队列中的元素是一个 pair,包含一个 TreeNode* 类型的节点指针和一个 unsigned long long 类型的位置编号。

初始化队列:将根节点和其位置编号1作为队列的第一个元素。

BFS遍历:使用 while 循环,只要队列不为空,就继续执行。循环中,首先获取队列中的元素数量 size,这代表了当前层的节点数。然后,通过访问队列的前端和后端,获取当前层的最左边和最右边节点的位置编号 left 和 right。

计算宽度:使用 maxWidth 变量来记录到目前为止遍历到的最大宽度。在每次循环中,更新 maxWidth 为当前层宽度和 maxWidth 中较大值。当前层的宽度通过 (right - left + 1) 计算得出。

节点处理:在循环的内部,使用一个 for 循环来处理当前层的每个节点。对于队列中的每个元素,首先获取节点指针 node 和其位置编号 pos,然后从队列中移除该元素。接着,检查当前节点是否有左子节点和右子节点,如果有,计算它们的位置编号并将其加入队列。左子节点的位置编号是当前节点位置编号的2倍,右子节点的位置编号是当前节点位置编号的2倍加1。

循环结束:当队列为空时,表示已经遍历完所有层的节点,此时 maxWidth 中存储的就是二叉树的最大宽度。

3.算法特点分析

数据结构:算法使用了队列作为主要的数据结构,以实现BFS遍历。队列中的元素是包含节点指针和位置编号的 pair,这使得算法能够在每一层结束时快速确定最左边和最右边的节点。

时间复杂度:算法的时间复杂度为 O(n),其中 n 是二叉树中的节点数。这是因为每个节点恰好被访问一次。

空间复杂度:算法的空间复杂度为 O(w),其中 w 是二叉树的最大宽度。这是因为在任何给定时间,队列中最多会有 w 个节点。

位置编号:算法通过为每个节点分配一个位置编号来简化宽度的计算。这种方法避免了需要维护一个复杂的数据结构来跟踪每层的节点。

4.具体代码如下:


class Solution {
public:int widthOfBinaryTree(TreeNode* root) {if(root == nullptr)return 0;unsigned long long maxWidth = 0;queue<pair<TreeNode*,unsigned long long>> q;  // 使用队列保存每个节点和它对应的位置编号q.push(pair{root, 1});while(!q.empty()){int size = q.size();unsigned long long left = q.front().second;  // 当前层最左边节点的位置编号unsigned long long right = q.back().second;  // 当前层最右边节点的位置编号maxWidth = max(maxWidth, (right - left + 1));  // 计算当前层的宽度for(int i = 0; i < size; i++){TreeNode* node = q.front().first;unsigned long long pos = q.front().second;q.pop();if(node->left)q.push(pair{node->left, pos * 2});  // 左子节点的位置编号是当前节点的位置编号乘以2if(node->right)q.push(pair{node->right, pos * 2 + 1});  // 右子节点的位置编号是当前节点的位置编号乘以2加1}}return maxWidth;}
};

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

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

相关文章

把 网页代码 嵌入到 单片机程序中 2 日志2024/7/26

之前不是说把 网页代码 嵌入到 单片机程序中 嘛! 目录 之前不是说把 网页代码 嵌入到 单片机程序中 嘛! 修改vs的tasks.json配置 然后 测试 结果是正常的,可以编译了 但是:当我把我都html代码都写上去之后 还是会报错!!! 内部被检测到了,没辙,只有手动更新了小工具代码 …

Python3网络爬虫开发实战(2)爬虫基础库

文章目录 一、urllib1. urlparse 实现 URL 的识别和分段2. urlunparse 用于构造 URL3. urljoin 用于两个链接的拼接4. urlencode 将 params 字典序列化为 params 字符串5. parse_qs 和 parse_qsl 用于将 params 字符串反序列化为 params 字典或列表6. quote 和 unquote 对 URL的…

JAVAWeb实战(前端篇)

项目实战一 0.项目结构 1.创建vue3项目&#xff0c;并导入所需的依赖 npm install vue-router npm install axios npm install pinia npm install vue 2.定义路由&#xff0c;axios&#xff0c;pinia相关的对象 文件&#xff08;.js&#xff09; 2.1路由(.js) import {cre…

HarmonyOS Next 省市区级联(三级联动)筛选框

效果图 完整代码 实例对象 export class ProvinceBean {id?: stringpid?: stringisSelect?: booleandeep?: objectextName?: stringchildren?: ProvinceBean[] }级联代码 import { MMKV } from tencent/mmkv/src/main/ets/utils/MMKV import { ProvinceBean } from ..…

nodeselector

1.概述 在创建pod资源是&#xff0c;k8s集群系统会给我们将pod资源随机分配到不同服务器上。我们通过配置nodeSelector可以将pod资源指定到拥有某个标签的服务器上 使用nodeselector前我们要先给每个节点打上标签&#xff0c;在编辑pod资源的时候选择该标签 2.示例 给节点打标…

数据科学统计面试问题 -40问

前 40 名数据科学统计面试问题 一、介绍 正如 Josh Wills 曾经说过的那样&#xff0c;“数据科学家是一个比任何程序员都更擅长统计、比任何统计学家都更擅长编程的人”。统计学是数据科学中处理数据及其分析的基本工具。它提供了工具和方法&#xff0c;可帮助数据科学家获得…

初涉JVM

JVM 字节码、类的生命周期、内存区域、垃圾回收 JVM主要功能&#xff1a; 解释运行&#xff08;翻译字节码&#xff09;内存管理&#xff08;GC&#xff09;即使编译&#xff08;Just - In - Time&#xff0c; JIT&#xff09; 将短时间内常使用到的字节码翻译成机器码存储在内…

【Gin】智慧架构的巧妙砌筑:Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下)

【Gin】智慧架构的巧妙砌筑&#xff1a;Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下) 大家好 我是寸铁&#x1f44a; 【Gin】智慧架构的巧妙砌筑&#xff1a;Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下)✨ 喜欢的小伙伴可以点点关注 &#x1f49d; …

uboot的mmc partconf命令

文章目录 命令格式参数解释具体命令解释总结 mmc partconf 是一个用于配置 MMC (MultiMediaCard) 分区的 U-Boot 命令。具体来说&#xff0c;这个命令允许你设置或读取 MMC 卡的分区配置参数。让我们详细解释一下 mmc partconf 0 0 1 0 命令的含义。 命令格式 mmc partconf &…

【网络安全】子域名模糊测试实现RCE

未经许可&#xff0c;不得转载。 文章目录 正文总结 正文 在之前测试一个私人项目时&#xff0c;我报告了admin.Target.com上的Auth Bypass漏洞&#xff0c;这将导致SQLI&RCE &#xff0c;该漏洞在报告后仅一天就被修复。 现在重拾该应用程序&#xff0c;对子域进行模糊测…

探索 Blockly:自定义积木实例

3.实例 3.1.基础块 无输入 , 无输出 3.1.1.json var textOneJson {"type": "sql_test_text_one","message0": " one ","colour": 30,"tooltip": 无输入 , 无输出 };javascriptGenerator.forBlock[sql_test_te…

c语言第四天笔记

关于 混合操作&#xff0c;不同计算结果推理 第一种编译结果&#xff1a; int i 5; int sum (i) (i) 6 7 13 第二种编译结果&#xff1a; int i 5; int sum (i) (i) 6 7 7 7 前面的7是因为后面i的变化被影响后&#xff0c;重新赋值 14 第一种编译结果&#xff…

后端解决跨域(Cross-Origin Resource Sharing)(三种方式)

注解CrossOrigin 控制层的类上或者方法上加注解CrossOrigin 实现接口并重写方法 Configuration public class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {// 设置允许跨域的路径registry.addMapping("/**&qu…

springboot配置文件如何读取pom.xml的值

比如想读取profile.active的值&#xff0c;默认属性为pro 在maven中加入以下插件&#xff1a; <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.2.0</version>&l…

Servlet详解(超详细)

Servlet详解 文章目录 Servlet详解一、基本概念二、Servlet的使用1、创建Servlet类2、配置Servleta. 使用web.xml配置b. 使用注解配置 3、部署Web应用4、处理HTTP请求和生成响应5、处理表单数据HTML表单Servlet 6、管理会话 三、servlet生命周期1、加载和实例化2、初始化3、 请…

pinia安装及简介

pinia简介 基本特点 轻量级&#xff1a;Pinia相比于传统的Vuex&#xff0c;体积更小&#xff0c;性能更好&#xff0c;只有大约1KB左右。 简化API&#xff1a;Pinia简化了状态管理库的使用方法&#xff0c;抛弃了Vuex中的mutations&#xff0c;只保留了state、getters和actions…

科普文:docker基础概念、软件安装和常用命令

docker基本概念 一 容器的概念 1. 什么是容器&#xff1a;容器是在隔离的环境里面运行的一个进程&#xff0c;这个隔离的环境有自己的系统目录文件&#xff0c;有自己的ip地址&#xff0c;主机名等。也可以说&#xff1a;容器是一种轻量级虚拟化的技术。 2. 容器相对于kvm虚…

基于Golang+Vue3快速搭建的博客系统

WANLI 博客系统 项目介绍 基于vue3和gin框架开发的前后端分离个人博客系统&#xff0c;包含md格式的文本编辑展示&#xff0c;点赞评论收藏&#xff0c;新闻热点&#xff0c;匿名聊天室&#xff0c;文章搜索等功能。 项目在线访问&#xff1a;http://bloggo.chat/ 访客账号…

SMU Summer 2024 Contest Round 7

Bouquet 思路&#xff1a; 总的方案数就是C(n,1)C(n,2) . . . . C(n,n) &#xff1b;然后不符合的方案数为C(n,a)C(n,b); 两者相减就是答案&#xff1b;因为算组合数时&#xff0c;数据非常大&#xff0c;所以要用到lucas定理来计算组合数的大小&#xff1b; 当同余定理用…

C#使用Clipper2进行多边形合并、相交、相减、异或的示例

Clipper2库介绍 开源库介绍&#xff1a; Clipper2在Github上的地址&#xff1a;https://github.com/AngusJohnson/Clipper2 Clipper2库对简单和复杂多边形执行交集&#xff08;Intersection&#xff09;、并集&#xff08;Union&#xff09;、差分&#xff08;Difference&…