当前位置: 首页 > news >正文

LeetCode往完全二叉树添加节点

剑指 Offer II 043. 往完全二叉树添加节点

完全二叉树是每一层(除最后一层外)都是完全填充(即,节点数达到最大,第 n 层有 2n-1 个节点)的,并且所有的节点都尽可能地集中在左侧。

设计一个用完全二叉树初始化的数据结构 CBTInserter,它支持以下几种操作:

CBTInserter(TreeNode root) 使用根节点为 root 的给定树初始化该数据结构;
CBTInserter.insert(int v) 向树中插入一个新节点,节点类型为 TreeNode,值为 v 。使树保持完全二叉树的状态,并返回插入的新节点的父节点的值;
CBTInserter.get_root() 将返回树的根节点。

输入:inputs = [“CBTInserter”,“insert”,“get_root”], inputs = [[[1]],[2],[]]
输出:[null,1,[1,2]]

来源:LeetCode

首先想到的就是层序遍历,利用层序遍历找到符合条件的父节点,查看它的左孩子和右孩子,如果左孩子为null,就新添加节点作为它的左孩子,如果左孩子不为null,右孩子为null,就添加其右孩子节点。

class CBTInserter {
    TreeNode root;
    
    public CBTInserter(TreeNode root) {
        this.root=root;
    }
    
    public int insert(int v) {
        int ans=0;
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
        queue.offer(root);
        if(root==null){
            return v;
        }
        TreeNode t = root;
        while(!queue.isEmpty()){
            t = queue.poll();
            if(t.left!=null)
            {
                queue.offer(t.left);
            }
            else
            {
                TreeNode tleft = new TreeNode(v);
                t.left=tleft;
                ans = t.val;
                break;
            }
            if(t.right!=null){
                queue.offer(t.right);
            }
            if(t.right==null){
                TreeNode tright = new TreeNode(v);
                t.right = tright;
                ans = t.val;
                break;
            }
            
        }
        return ans;
    }
    
    public TreeNode get_root() {
        return root;
    }
}

注意t应该是队首的节点。

在编码的时候碰到了问题:如果将queue定义为全局变量就会导致有的节点的右孩子考虑不到(因为用了break操作,就有可能不会去判断某个节点的右孩子是否为null,而是直接下一个节点)。

官方题解中给出了另一种解法
申请两个队列,分别进行层序遍历和选出符合条件的父节点。
每次要插入元素时就从候选队列找到队首元素,将插入节点作为它的孩子节点,并将孩子节点也要进入队列。
当然要注意,如果队首的元素左右孩子节点都已经不为null,那该节点就应该出队列。

class CBTInserter {
    TreeNode root;
    Queue<TreeNode> cur = new ArrayDeque<TreeNode>();
    public CBTInserter(TreeNode root) {
        this.root=root;
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
        TreeNode t = root;
        queue.offer(root);
        while(!queue.isEmpty()){
            t = queue.poll();
            if(t.left!=null)
            {
                queue.offer(t.left);
            }
            if(t.right!=null){
                queue.offer(t.right);
            }
            if(t.left==null||t.right==null){
                cur.offer(t);
            }
        }
    }
    
    public int insert(int v) {
        
        if(root==null){
            return v;
        }
        TreeNode res = cur.peek();
        
        TreeNode node = new TreeNode(v);
       
        if(res.left==null)
        {
            
            res.left=node;
        }
        else{
            res.right=node;
            cur.poll();
        }
        cur.offer(node);
        
        return res.val;
    }
    
    public TreeNode get_root() {
        return root;
    }
}

千万千万注意一定要将新的节点(既没有左孩子也没有右孩子)加入到cur队列里,否则有可能会造成cur队列为null。
CBTInserter(TreeNode root)方法里面的层序遍历只能遍历题目给出的树,将其符合的节点加入cur。

相关文章:

  • Linux、docker、kubernetes、MySql、Shell运维快餐
  • 基数(桶)排序算法详解之C语言版
  • 生成模型的中Attention Mask说明
  • java毕业设计企业固定资产管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
  • Java---Java Web---JSP
  • opencv 机器学习-人脸识别
  • JavaScript的函数
  • java基于springboot+vue基本微信小程序的乒乓球课程管理系统 uniapp小程序
  • 安装数据库中间件——Mycat
  • 爬虫之Scrapy框架
  • 哈工大李治军老师操作系统笔记【23】:内存换出(Learning OS Concepts By Coding Them !)
  • Ubuntu 20.04 设置开机自启脚本
  • Vue2封装评论组件详细讲解
  • java-php-python-springboot校园新闻趣事计算机毕业设计
  • 使用Docker Compose搭建WordPress博客
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • Angular 响应式表单 基础例子
  • canvas绘制圆角头像
  • JavaScript创建对象的四种方式
  • Laravel Mix运行时关于es2015报错解决方案
  • MySQL的数据类型
  • Python学习之路13-记分
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • Vue 2.3、2.4 知识点小结
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 大主子表关联的性能优化方法
  • 分布式事物理论与实践
  • 记一次和乔布斯合作最难忘的经历
  • 老板让我十分钟上手nx-admin
  • 区块链技术特点之去中心化特性
  • 使用 Docker 部署 Spring Boot项目
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • # 数论-逆元
  • #include
  • #控制台大学课堂点名问题_课堂随机点名
  • ${factoryList }后面有空格不影响
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (02)Hive SQL编译成MapReduce任务的过程
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (6)添加vue-cookie
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (JS基础)String 类型
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .NET 服务 ServiceController