二叉树题目:二叉树最大宽度

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 前言
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:二叉树最大宽度

出处:662. 二叉树最大宽度

难度

5 级

题目描述

要求

给定一个二叉树的根结点 root \texttt{root} root,返回给定的树的最大宽度

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

每一层的宽度定义为两端结点(最左和最右的非空结点)之间的长度,两端结点之间的空结点也计入长度的计算。

题目保证答案在 32 \texttt{32} 32 为有符号整数范围内。

示例

示例 1:

示例 1

输入: root = [1,3,2,5,3,null,9] \texttt{root = [1,3,2,5,3,null,9]} root = [1,3,2,5,3,null,9]
输出: 4 \texttt{4} 4
解释:最大宽度出现在第 3 \texttt{3} 3 层,宽度为 4 \texttt{4} 4 5,3,null,9 \texttt{5,3,null,9} 5,3,null,9)。

示例 2:

示例 2

输入: root = [1,3,null,5,3] \texttt{root = [1,3,null,5,3]} root = [1,3,null,5,3]
输出: 2 \texttt{2} 2
解释:最大宽度出现在第 3 \texttt{3} 3 层,宽度为 2 \texttt{2} 2 5,3 \texttt{5,3} 5,3)。

示例 3:

示例 3

输入: [1,3,2,5] \texttt{[1,3,2,5]} [1,3,2,5]
输出: 2 \texttt{2} 2
解释:最大宽度出现在树的第 2 \texttt{2} 2 层,宽度为 2 \texttt{2} 2 3,2 \texttt{3,2} 3,2)。

数据范围

  • 树中结点数目在范围 [1, 3000] \texttt{[1, 3000]} [1, 3000]
  • -100 ≤ Node.val ≤ 100 \texttt{-100} \le \texttt{Node.val} \le \texttt{100} -100Node.val100

前言

为了得到二叉树的最大宽度,需要得到二叉树每一层中的每个结点的位置。每一层的宽度取决于该层最左和最右的非空结点的位置,除了根结点以外的每个结点的位置由该结点的父结点和该结点是左子结点还是右子结点决定。

考虑满二叉树每一层中的每个结点的位置。定义根结点位于第 0 0 0 层,则满二叉树的第 k k k 层有 2 k 2^k 2k 个结点,从左到右的每个结点的位置依次是 0 0 0 2 k − 1 2^k - 1 2k1,满二叉树的第 k + 1 k + 1 k+1 层有 2 k + 1 2^{k + 1} 2k+1 个结点,从左到右的每个结点的位置依次是 0 0 0 2 k + 1 − 1 2^{k + 1} - 1 2k+11。由于满二叉树的第 k + 1 k + 1 k+1 层的结点数目是第 k k k 层的结点数目的 2 2 2 倍,因此对于第 k k k 层中位置是 pos \textit{pos} pos 的结点,其左子结点和右子结点在第 k + 1 k + 1 k+1 层中的位置分别是 pos × 2 \textit{pos} \times 2 pos×2 pos × 2 + 1 \textit{pos} \times 2 + 1 pos×2+1

上述关于结点位置的定义同样适用于不是满二叉树的情况。对于每个非空结点,只要知道该结点在当前层中的位置,即可知道该结点的每个子结点在下一层中的位置,因此可以知道每个结点在对应层中的位置。

解法一

思路和算法

由于需要计算二叉树每一层的宽度,然后得到最大宽度,因此可以使用层序遍历实现。

从根结点开始依次遍历每一层的结点,在层序遍历的过程中需要区分不同结点所在的层,确保每一轮访问的结点为同一层的全部结点。遍历每一层结点之前首先得到当前层的结点数,即可确保每一轮访问的结点为同一层的全部结点。对于每一层,记录该层的最左和最右非空结点的位置,然后计算该层的宽度。

为了记录每个结点的位置,需要使用两个队列,分别存储结点和结点的位置,这两个队列分别为结点队列和位置队列,初始时将根结点和位置 0 0 0 分别入两个队列。在遍历每一层之前,位置队列的队首元素即为该层的最左非空结点的位置,遍历该层的每个结点时,将每个结点的非空子结点和子结点对应的位置分别入两个队列,该层的最后一个结点即为该层的最右非空结点,计算两端结点之间的长度,得到该层的宽度,并用该层的宽度更新最大宽度。

遍历结束之后,即可得到二叉树的最大宽度。

代码

class Solution {public int widthOfBinaryTree(TreeNode root) {int maxWidth = 0;Queue<TreeNode> nodeQueue = new ArrayDeque<TreeNode>();Queue<Integer> posQueue = new ArrayDeque<Integer>();nodeQueue.offer(root);posQueue.offer(0);while (!nodeQueue.isEmpty()) {int leftmost = posQueue.peek();int size = nodeQueue.size();for (int i = 0; i < size; i++) {TreeNode node = nodeQueue.poll();int pos = posQueue.poll();if (i == size - 1) {int width = pos - leftmost + 1;maxWidth = Math.max(maxWidth, width);}TreeNode left = node.left, right = node.right;if (left != null) {nodeQueue.offer(left);posQueue.offer(pos * 2);}if (right != null) {nodeQueue.offer(right);posQueue.offer(pos * 2 + 1);}}}return maxWidth;}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是队列空间,队列内元素个数不超过 n n n

解法二

思路和算法

也可以使用深度优先搜索计算二叉树最大宽度。具体做法是使用前序遍历,依次访问二叉树的根结点、左子树和右子树,由于前序遍历满足同一层结点被访问的顺序为从左到右,因此同一层结点中第一个被访问的结点一定是该层最左的非空结点。使用哈希表存储每一层的最左的非空结点的位置(以下简称「最左位置」),当访问到某个结点时,如果哈希表中没有该结点所在层的最左位置,则在哈希表中将当前层对应的最左位置设为该结点的位置。

对于访问到的每个非空结点,可以得到当前层内该结点的位置和最左位置,计算当前层内该结点和最左的非空结点之间的宽度,并更新二叉树的最大宽度。遍历结束之后,即可得到二叉树的最大宽度。

代码

class Solution {Map<Integer, Integer> leftmostMap = new HashMap<Integer, Integer>();int maxWidth = 0;public int widthOfBinaryTree(TreeNode root) {dfs(root, 0, 0);return maxWidth;}public void dfs(TreeNode node, int depth, int pos) {leftmostMap.putIfAbsent(depth, pos);maxWidth = Math.max(maxWidth, pos - leftmostMap.get(depth) + 1);TreeNode left = node.left, right = node.right;if (left != null) {dfs(left, depth + 1, pos * 2);}if (right != null) {dfs(right, depth + 1, pos * 2 + 1);}}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是哈希表和栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)

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

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

相关文章

完全免费!超好用的IDEA插件推荐:Apipost-Helper

Idea 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它可以帮助开发人员更加高效地编写、调试和部署软件应用程序,Idea 还具有许多插件和扩展&#xff0c;可以根据开发人员的需要进行定制和扩展&#xff0c;从而提高开发效率,今天我们就来介绍一款国产的…

未来之选:为什么向量数据库是您的数据管理利器

文章目录 前言什么是向量数据库&#xff1f;向量数据库的机制向量数据库的优点‍查询向量数据库 什么是向量Embedding&#xff1f;Amazon OpenSearch Service总结 前言 向量数据库擅长处理复杂的高维数据&#xff0c;正在彻底改变商业世界的数据检索和分析。它们执行相似性搜索…

【Unity插件】2D模拟绳子的插件——Rope 2D Editor

文章目录 前言资源unity商店地址&#xff1a;我这里有一个比较老旧的版本&#xff1a; 使用创建绳子场景使用时效果 参考完结 前言 最近发现一个很有意思的插件Rope 2D Editor&#xff0c;这是一个简单而强大的 2d 绳索编辑器。这是我为我的游戏&#xff08;Dabdob&#xff09…

Linux——vim简介、配置方案(附带超美观的配置方案)、常用模式的基本操作

vim简介、配置方案、常用模式的基本操作 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的xmind和.png文件都已同步导入至资源 1. vim简介 vim是Linux常用的文本编辑器&#xff0c;每个Linux账户都独有一个vim编辑器 本篇我们介绍vim最常用的三种模式&#xff1a;…

网络安全之认识托管威胁检测与响应(MDR)

随着数字化转型加速&#xff0c;企业的IT环境日益复杂&#xff0c;面临的网络安全威胁也在不断增加。传统的防御措施已经无法有效应对新型威胁&#xff0c;而且很多企业缺乏专业的网络安全团队和技术手段&#xff0c;导致大量的安全事件未能及时被发现和处理。 在这种背景下&a…

[Mac软件]Adobe Media Encoder 2024 V24.0.2免激活版

软件说明 使用Media Encoder&#xff0c;您将能够处理和管理多媒体。插入、转码、创建代理版本&#xff0c;并几乎以任何可用的格式输出。在应用程序中以单一方式使用多媒体&#xff0c;包括Premiere Pro、After Effects和Audition。 紧密整合 与Adobe Premiere Pro、After …

学用 DevChat 的 VSCode 插件,体验AI智能编程工具 (一)

简单说DevChat是一个辅助编程的智能工具&#xff0c;它可以通过自然语言对话的方式与开发者进行交流&#xff0c;帮助开发者更高效地完成编程任务。 有了人工智能工具&#xff0c;编程进入一个新天地。 闻名已久&#xff0c;不若体验一下。 一.准备工作 1.运行环境. A. p…

京东商品详情API接口使用方法以及示例代码,可高并发请求

京东商品详情API接口是一种用于获取京东商品详细信息的接口。通过该接口&#xff0c;开发人员可以获取到商品的ID、名称、价格、销量、评价等信息&#xff0c;从而进行进一步的数据分析和应用开发。本文将介绍京东商品详情API接口的使用方法、注意事项以及示例代码。 一、使用…

开放领域问答机器人2——开发流程和方案

开放领域问答机器人是指在任何领域都能够回答用户提问的智能机器人。与特定领域问答机器人不同&#xff0c;开放领域问答机器人需要具备更广泛的知识和更灵活的语义理解能力&#xff0c;以便能够回答各种不同类型的问题。 开发开放领域问答机器人的流程和方案可以包括以下步骤…

MySQL | 查询接口性能调优、编码方式不一致导致索引失效

背景 最近业务反馈&#xff0c;列表查询速度过慢&#xff0c;需要优化。 到正式环境系统去验证&#xff0c;发现没筛选任何条件的情况下&#xff0c;查询需要三十多秒&#xff0c;而筛选了条件之后需要13秒。急需优化。 先说结论&#xff1a;连表用的字段编码方式不一致导致索…

达梦数据库答案

1、 创建数据库实例&#xff0c;到/dm8/data下&#xff0c;数据库名&#xff1a;DEMO&#xff0c;实例名DEMOSERVER&#xff08;10分&#xff09; [dmdbadmServer ~]$ cd /dm8/tool [dmdbadmServer tool]$ ./dbca.sh1、 簇大小32&#xff0c;页大小16&#xff0c;登录密码&…

第12章 PyTorch图像分割代码框架-3:推理与部署

推理模块 模型训练完成后&#xff0c;需要单独再写一个推理模块来供用户测试或者使用&#xff0c;该模块可以命名为test.py或者inference.py&#xff0c;导入训练好的模型文件和待测试的图像&#xff0c;输出该图像的分割结果。inference.py主体部分如代码11-7所示。 代码11-7 …

性能测试:Jenkins+Ant+Jmeter自动化框架的搭建方法

前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入&#xff0c;我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段&#xff0c;需要在每个版本中&#xff0c;对某些新增接口进行性能测试&#xff0c;有时还需要在一天中的不同时段分别进行…

Python数据结构:元组(Tuple)详解

1.介绍和基础操作 Python中的元组&#xff08;Tuple&#xff09;是不可变有序序列&#xff0c;可以容纳任意数据类型&#xff08;包括数字、字符串、布尔型、列表、字典等&#xff09;的元素&#xff0c;通常用圆括号() 包裹。与列表&#xff08;List&#xff09;类似&#xff…

【matlab】KMeans KMeans++实现手写数字聚类

目录 matlab代码kmeans matlab代码kmeans MNIST DATABASE下载网址: http://yann.lecun.com/exdb/mnist/ 聚类 将物理或抽象对象的集合分成由类似特征组成的多个类的过程称为聚类(clustering)。 对于给定N个n维向量x1&#xff0c;…&#xff0c;xN∈Rn&#xff0c;聚类的目标…

iOS如何通过在线状态来监听其他设备登录的状态

前提条件 1、完成 3.9.1 或以上版本 SDK 初始化 2、了解环信即时通讯 IM API 的 使用限制。 3、已联系商务开通在线状态订阅功能 实现方法 你可以通过调用 subscribe 方法订阅自己的在线状态&#xff0c;从而可以监听到其他设备在登录和离线时的回调&#xff0c;示例代码如下…

Javaweb之javascript的详细解析

1.5.1.2 String对象 语法格式 String对象的创建方式有2种&#xff1a; 方式1&#xff1a; var 变量名 new String("…") ; //方式一 例如&#xff1a; var str new String("Hello String"); 方式2&#xff1a; var 变量名 "…" ; //方…

美颜与性能的平衡:视频直播美颜SDK集成与性能优化指南

目前美颜SDK所遇到的挑战是如何在追求美颜效果的同时保持系统性能的稳定。本文将深入探讨视频直播美颜SDK的集成以及性能优化的关键指南&#xff0c;以帮助开发者找到合适的平衡点。 一、美颜SDK的集成 1.选择适用于直播的美颜SDK 在美颜SDK的众多选择中&#xff0c;要考虑…

【SpringBoot3+Vue3】一【基础篇】

目录 一、Spring Boot概述 1、Spring Boot 特性 1.1 起步依赖 1.2 自动配置 1.3 其他特性 1.3.1 内嵌的Tomcat、Jetty (无需部署WAR文件) 1.3.2 外部化配置 1.3.3 不需要XML配置(properties/yml) 二、Spring Boot入门 1、一个入门程序需求 2、步骤 2.1 创建Maven工…