二叉树题目:完全二叉树插入器

news2024/12/23 4:32:19

文章目录

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

题目

标题和出处

标题:完全二叉树插入器

出处:919. 完全二叉树插入器

难度

6 级

题目描述

要求

完全二叉树是每一层(除最后一层外)都是完全填充的,并且所有的结点都尽可能地集中在左侧。

设计一种算法,将一个新结点插入到一个完全二叉树中,并在插入后保持完全二叉树。

实现 CBTInserter \texttt{CBTInserter} CBTInserter 类:

  • CBTInserter(TreeNode   root) \texttt{CBTInserter(TreeNode root)} CBTInserter(TreeNode root) 使用完全二叉树的根结点 root \texttt{root} root 初始化数据结构;
  • int   insert(int   v) \texttt{int insert(int v)} int insert(int v) 向树中插入一个值为 val \texttt{val} val 的新结点,使树保持完全二叉树的状态,并返回插入结点的父结点的值;
  • TreeNode   get_root() \texttt{TreeNode get\_root()} TreeNode get_root() 返回树的头结点。

示例

示例 1:

示例 1

输入:
["CBTInserter",   "insert",   "insert",   "get_root"] \texttt{["CBTInserter", "insert", "insert", "get\_root"]} ["CBTInserter", "insert", "insert", "get_root"]
[[[1,   2]],   [3],   [4],   []] \texttt{[[[1, 2]], [3], [4], []]} [[[1, 2]], [3], [4], []]
输出:
[null,   1,   2,   [1,   2,   3,   4]] \texttt{[null, 1, 2, [1, 2, 3, 4]]} [null, 1, 2, [1, 2, 3, 4]]
解释:
CBTInserter   cBTInserter   =   new   CBTInserter([1,   2]); \texttt{CBTInserter cBTInserter = new CBTInserter([1, 2]);} CBTInserter cBTInserter = new CBTInserter([1, 2]);
cBTInserter.insert(3); \texttt{cBTInserter.insert(3);} cBTInserter.insert(3); // 返回 1 \texttt{1} 1
cBTInserter.insert(4); \texttt{cBTInserter.insert(4);} cBTInserter.insert(4); // 返回 2 \texttt{2} 2
cBTInserter.get_root(); \texttt{cBTInserter.get\_root();} cBTInserter.get_root(); // 返回 [1,   2,   3,   4] \texttt{[1, 2, 3, 4]} [1, 2, 3, 4]

数据范围

  • 树中结点数目在范围 [1,   1000] \texttt{[1, 1000]} [1, 1000]
  • 0 ≤ Node.val ≤ 5000 \texttt{0} \le \texttt{Node.val} \le \texttt{5000} 0Node.val5000
  • root \texttt{root} root 是完全二叉树
  • 0 ≤ val ≤ 5000 \texttt{0} \le \texttt{val} \le \texttt{5000} 0val5000
  • 最多调用 10 4 \texttt{10}^\texttt{4} 104 insert \texttt{insert} insert get_root \texttt{get\_root} get_root

解法

思路和算法

这道题的解法不唯一。一种常规的解法是维护完全二叉树中的结点数,每次插入结点时根据结点数定位到插入结点的位置。当完全二叉树中有 n n n 个结点时,该解法每次插入操作的时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

利用完全二叉树的性质,可以将每次插入操作的时间复杂度降低到 O ( 1 ) O(1) O(1)

由于完全二叉树的结点插入顺序和层序遍历相同,因此在初始化时可以使用层序遍历访问完全二叉树中的每个结点。每次插入的结点的父结点一定是层序遍历访问到的第一个存在空子结点的结点,父结点满足两个子结点都为空或者只有右子结点为空。如果父结点的两个子结点都为空,则插入的结点作为父结点的左子结点;如果父结点的子结点中只有右子结点为空,则插入的结点作为父结点的右子结点。

如果一个结点的两个子结点都不为空,则下一个插入的结点的父结点一定是层序遍历顺序中当前结点后面的结点。因此,维护完全二叉树的根结点和队列,即可实现每次插入使用 O ( 1 ) O(1) O(1) 的时间完成。

初始化时将根结点入队列,然后执行如下操作:如果队首结点的两个子结点都不为空,则将队首结点出队列,并将队首结点的左子结点和右子结点依次入队列。重复该操作直到队首结点的两个子结点中至少有一个为空。

对于插入结点操作,使用给定的结点值创建新结点,此时队首结点即为插入结点的父结点。执行如下操作。

  1. 判断父结点的左子结点是否为空,执行相应的操作。

    • 如果父结点的左子结点为空,则将新结点作为父结点的左子结点。

    • 如果父结点的左子结点不为空,则将新结点作为父结点的右子结点,然后将父结点出队列,并将父结点的左子结点和右子结点依次入队列。

  2. 返回父结点值。

对于返回根结点操作,返回完全二叉树的根结点即可。

代码

class CBTInserter {
    TreeNode root;
    Queue<TreeNode> queue;

    public CBTInserter(TreeNode root) {
        this.root = root;
        queue = new ArrayDeque<TreeNode>();
        queue.offer(root);
        while (queue.peek().left != null && queue.peek().right != null) {
            TreeNode node = queue.poll();
            queue.offer(node.left);
            queue.offer(node.right);
        }
    }
    
    public int insert(int val) {
        TreeNode insertNode = new TreeNode(val);
        TreeNode node = queue.peek();
        if (node.left == null) {
            node.left = insertNode;
        } else {
            node.right = insertNode;
            queue.poll();
            queue.offer(node.left);
            queue.offer(node.right);
        }
        return node.val;
    }
    
    public TreeNode get_root() {
        return root;
    }
}

复杂度分析

  • 时间复杂度:构造方法的时间复杂度是 O ( n ) O(n) O(n),插入结点操作和返回根结点操作的时间复杂度都是 O ( 1 ) O(1) O(1),其中 n n n 是二叉树的结点数。构造方法需要对完全二叉树层序遍历,需要 O ( n ) O(n) O(n) 的时间。插入结点操作将新结点作为父结点的子结点,可能有队列操作,需要 O ( 1 ) O(1) O(1) 的时间。返回根结点操作直接返回完全二叉树的根结点,需要 O ( 1 ) O(1) O(1) 的时间。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。需要存储完全二叉树以及使用队列存储完全二叉树中的子结点不完全的结点。

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

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

相关文章

线索系统性能优化实践

引言 在京东家居事业部&#xff0c;线索CRM系统扮演着至关重要的角色&#xff0c;它作为构建家居场景核心解决方案集的首要环节&#xff0c;肩负着获客和拓展业务的重要使命。然而&#xff0c;随着业务的不断扩张和市场需求的日益增长&#xff0c;系统原有的架构开始显露出诸多…

DDMS修改默认端口8700

当前操作系统为 Mac&#xff0c;编辑器 Intellij IDE 准备工作&#xff1a;在IDE中的终端下&#xff0c;输入monitor指令 > 回车&#xff0c;打开DDMS 1、第一步&#xff0c; 2、第二步&#xff1a;修改静态端口 3、第三步 4、第四步&#xff1a;修复配置端口 5、第五步 重…

高级路由学习试题

文章目录 高级路由学习试题一.高级路由题目答案 二.OSPF 相关答案 三.基础知识答案 高级路由学习试题 一.高级路由题目 1.以下属于ITOIP特性的有&#xff08;&#xff09; A、智能 B、开放 C、融合 D、标准 2.层级化网络模型将网络划分为&#xff08;&#xff09; A、汇…

[Kubernetes]9. K8s ingress讲解借助ingress配置http,https访问k8s集群应用

前面讲解了使用Helm部署mysql集群,这里来看看使用Ingress搭建负载均衡功能 1.介绍 功能类似 Nginx ,可以根据域名、路径把请求转发到不同的 Service , Ingress 为外部访问集群提供了一个 统一 入口, 避免 了 对外暴露集群端口 ,可以配置 https,http访问集群应用,接下来看看如…

实现STM32烧写程序-(1)获取Bootloader版本信息

简介 如何像ST Flash Loader等工具一样写自己的烧写程序呢?文档 AN3155: USART protocol used in the STM32 bootloader 步骤 Boot模式 将 开发板例如STM32F103C8T6 Boot0->1 & Boo1->0 重启或复位进入系统存储模式 物理连接 将USART1 通过 USB转TTL线连接到…

大模型学习与实践笔记(五)

一、环境配置 1. huggingface 镜像下载 sentence-transformers 开源词向量模型 import os# 设置环境变量 os.environ[HF_ENDPOINT] https://hf-mirror.com# 下载模型 os.system(huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-…

一卡通水控电控开发踩过的坑

最近在做一个项目&#xff0c;是对接一卡通设备的。我一开始只拿到设备和3个文档开局。不知道从哪下手。一步一步踩坑过来。踩了很多没有必要的坑&#xff0c;写出来给有用的人吧。 读卡器怎么用&#xff1f; 有个读卡器&#xff0c;一开始什么软件也不提供。我都不知道是干嘛…

Spring Boot - Application Events 的发布顺序_ApplicationContextInitializedEvent

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c…

NLP论文阅读记录 - 05 | 2023 抽象总结与提取总结:实验回顾

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1 提取方法2.2 抽象方法2.3 数据集 三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 Abstractive vs. Extractiv…

从头安装与使用一个docker GPU环境

GPU版docker的安装与使用 欢迎使用GPU版docker安装使用说明使用官方教程安装docker新建一个GPU版docker环境调用docker环境执行本地python文件 欢迎使用GPU版docker安装使用说明 使用官方教程安装docker 导入源仓库的GPG key curl -fsSL https://download.docker.com/linux/…

RTL编码(1)——概述

一、RTL级描述 RTL&#xff08;Register Transfer Level&#xff09;级&#xff1a;寄存器&#xff0b;组合逻辑&#xff0c;其功能与时序用Verilog HDL&#xff08;以下简称Verilog&#xff09;或VHDL代码描述。 RTL描述包含了同步数字电路最重要的三个特征&#xff1a;组合逻…

水产冷链物流行业零下25℃库架一体 海格里斯HEGERLS四向穿梭式冷藏冷库智能密集仓

随着国内外仓储物流整体规模和低温产品消费需求的稳步增长&#xff0c;冷链市场应用潜力不断释放。在传统“货架叉车”的方式下&#xff0c;货物、人员及机械设备不断进出&#xff0c;容易造成温度波动&#xff0c;导致冷量流失。立体冷库则以更高密度、更具成本效益的方式&…

electron+vue网页直接播放RTSP视频流?

目前大部分摄像头都支持RTSP协议&#xff0c;但是在浏览器限制&#xff0c;最新版的浏览器都不能直接播放RTSP协议&#xff0c;Electron 桌面应用是基于 Chromium 内核的&#xff0c;所以也不能直接播放RTSP&#xff0c;但是我们又有这个需求怎么办呢&#xff1f; 市场上的方案…

【动态规划】 【字典树】C++算法:472 连接词

作者推荐 【动态规划】458:可怜的小猪 涉及知识点 动态规划 字典树 LeetCode472 连接词 给你一个 不含重复 单词的字符串数组 words &#xff0c;请你找出并返回 words 中的所有 连接词 。 连接词 定义为&#xff1a;一个完全由给定数组中的至少两个较短单词&#xff08;不…

jenkins 自由风格部署vue项目,参数化构建vue项目

1. 丢弃旧的构建 2. 是否需要install 3. git 4. 配置node16: 5. 脚本&#xff1a; 脚本&#xff1a; #进入Jenkins工作空间下项目目录 cd /var/lib/jenkins/workspace/你的任务名称 node -v #检测node版本&#xff08;此条命令非必要&#xff09; npm -v #检测npm版本&#x…

【开源】基于JAVA语言的康复中心管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员模块 三、系统展示四、核心代码4.1 查询康复护理4.2 新增康复训练4.3 查询房间4.4 查询来访4.5 新增用药 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的康复中…

Linux ----冯诺依曼体系结构与操作系统

目录 前言 一、冯诺依曼体系结构 二、为什么选择冯诺依曼体系结构&#xff1f; 三、使用冯诺依曼结构解释问题 问题1&#xff1a; 问题2: 四、操作系统 1.操作系统是什么 2.为什么需要操作系统 3.操作系统怎样管理的 4.如何给用户提供良好环境 五、我们是怎样调用系…

imgaug库指南(18):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

CodeQL基本使用

0x01 安装codeql 去github下载一个对应版本的codeql捆绑包。 https://github.com/github/codeql-action/releases 然后解压&#xff0c;这里我是解压到桌面 然后用添加到环境变量中 然后在任意位置输入codeql命令&#xff0c;如果能有以下提示就表示安装成功 然后下载vscode…

戴尔服务器有8条内存条,开机有一条内存条自检提示出错,可以不用管他吗,有影响吗?

环境 戴尔R730 问题描述 戴尔服务器有8条内存条&#xff0c;开机有一条内存条自检提示出错&#xff0c;可以不用管他吗&#xff0c;有影响吗&#xff1f; 提示B1内存有问题 解决方案 不能&#xff0c;有影响&#xff0c;安装系统时卡住在启动节目无法正常安装&#xff0c;…