二叉树题目:输出二叉树

文章目录

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

题目

标题和出处

标题:输出二叉树

出处:655. 输出二叉树

难度

6 级

题目描述

要求

给定二叉树的根结点 root \texttt{root} root,创建 m × n \texttt{m} \times \texttt{n} m×n 的字符串矩阵 res \texttt{res} res 表示二叉树的格式化输出。格式化输出矩阵应根据以下规则创建:

  • 树的高度是 height \texttt{height} height,行数 m \texttt{m} m 应等于 height + 1 \texttt{height} + \texttt{1} height+1
  • 列数 n \texttt{n} n 应等于 2 height + 1 − 1 \texttt{2}^{\texttt{height} + \texttt{1}} - \texttt{1} 2height+11
  • 根结点放置在第一行的正中间(更正式而言,位于 res[0][(n   -   1)   /   2] \texttt{res[0][(n - 1) / 2]} res[0][(n - 1) / 2])。
  • 对于每个放置在矩阵中 res[r][c] \texttt{res[r][c]} res[r][c] 位置的结点,将其左子结点放置在 res[r + 1][c − 2 height − r − 1 ] \texttt{res[r} + \texttt{1][c} - \texttt{2}^{\texttt{height} - \texttt{r} - \texttt{1}}\texttt{]} res[r+1][c2heightr1],右子结点放置在 res[r + 1][c + 2 height − r − 1 ] \texttt{res[r} + \texttt{1][c} + \texttt{2}^{\texttt{height} - \texttt{r} - \texttt{1}}\texttt{]} res[r+1][c+2heightr1]
  • 重复该过程,直到所有结点都放置到矩阵中。
  • 所有空单元格应包含空字符串 "" \texttt{""} ""

返回创建的矩阵 res \texttt{res} res

示例

示例 1:

示例 1

输入: root   =   [1,2] \texttt{root = [1,2]} root = [1,2]
输出:
[["",   "1",   ""], \texttt{[["", "1", ""],} [["", "1", ""],
  ["2",   "",   ""]] \texttt{ ["2", "", ""]]}  ["2", "", ""]]

示例 2:

示例 2

输入: root   =   [1,2,3,null,4] \texttt{root = [1,2,3,null,4]} root = [1,2,3,null,4]
输出:
[["",   "",   "",   "1",   "",   "",   ""], \texttt{[["", "", "", "1", "", "", ""],} [["", "", "", "1", "", "", ""],
  ["",   "2",   "",   "",   "",   "3",   ""], \texttt{ ["", "2", "", "", "", "3", ""],}  ["", "2", "", "", "", "3", ""],
  ["",   "",   "4",   "",   "",   "",   ""]] \texttt{ ["", "", "4", "", "", "", ""]]}  ["", "", "4", "", "", "", ""]]

数据范围

  • 树中结点数目在范围 [1,   2 10 ] \texttt{[1, 2}^\texttt{10}\texttt{]} [1, 210]
  • -99 ≤ Node.val ≤ 99 \texttt{-99} \le \texttt{Node.val} \le \texttt{99} -99Node.val99
  • 树的高度在范围 [1,   10] \texttt{[1, 10]} [1, 10]

前言

这道题要求将给定的二叉树格式化输出,使用矩阵表示格式化输出的结果。由于矩阵的行数和列数由二叉树的高度决定,因此需要首先计算二叉树的高度,根据二叉树的高度计算矩阵的行数和列数,创建矩阵之后遍历二叉树并将每个结点值填入矩阵中的对应位置。

计算二叉树的高度可以使用「二叉树的最大深度」的做法,使用深度优先搜索或者广度优先搜索得到二叉树的高度。这道题中定义的二叉树的高度为从根结点到最远叶结点的路径上的边数,因此边界情况为只有一个结点的二叉树的高度是 0 0 0

得到二叉树的高度 height \textit{height} height 之后,即可得到矩阵的行数 m = height + 1 m = \textit{height} + 1 m=height+1,列数 n = 2 m − 1 n = 2^m - 1 n=2m1。创建矩阵之后,首先将根结点值填入矩阵的第 0 0 0 行第 n − 1 2 \dfrac{n - 1}{2} 2n1 列,然后遍历二叉树的其余结点并填入矩阵中的对应位置。

当一个结点的位置确定之后,可以根据该结点在矩阵中的行列下标以及二叉树的高度决定其子结点的位置。如果一个结点位于第 row \textit{row} row 行第 column \textit{column} column 列,则其左子结点位于第 row + 1 \textit{row} + 1 row+1 行第 column − 2 height − row − 1 \textit{column} - 2^{\textit{height} - \textit{row} - 1} column2heightrow1 列,其右子结点位于第 row + 1 \textit{row} + 1 row+1 行第 column + 2 height − row − 1 \textit{column} + 2^{\textit{height} - \textit{row} - 1} column+2heightrow1 列。

输出二叉树可以使用深度优先搜索或者广度优先搜索实现。

解法一

思路和算法

使用深度优先搜索输出二叉树时,首先将根结点值填入矩阵的第 0 0 0 行第 n − 1 2 \dfrac{n - 1}{2} 2n1 列,然后计算出非空子结点在矩阵中的位置,继续遍历非空子树并将其余的结点值填入矩阵,直到所有结点遍历完毕,此时所有结点值都填入矩阵中的对应位置。

整个过程是一个递归的过程,递归的终止条件是当前结点为叶结点,此时将当前结点值填入矩阵中的对应位置,然后直接返回。对于其余情况,在将当前结点值填入矩阵中的对应位置之后,对非空子结点执行递归。

代码

class Solution {
    List<List<String>> res = new ArrayList<List<String>>();
    int height;

    public List<List<String>> printTree(TreeNode root) {
        height = getHeight(root);
        int m = height + 1;
        int n = (1 << m) - 1;
        for (int i = 0; i < m; i++) {
            List<String> row = new ArrayList<String>();
            for (int j = 0; j < n; j++) {
                row.add("");
            }
            res.add(row);
        }
        dfs(root, 0, (n - 1) / 2);
        return res;
    }

    public int getHeight(TreeNode root) {
        TreeNode left = root.left, right = root.right;
        if (left == null && right == null) {
            return 0;
        }
        int leftHeight = left != null ? getHeight(left) : -1;
        int rightHeight = right != null ? getHeight(right) : -1;
        return Math.max(leftHeight, rightHeight) + 1;
    }

    public void dfs(TreeNode node, int row, int column) {
        res.get(row).set(column, String.valueOf(node.val));
        TreeNode left = node.left, right = node.right;
        if (left != null) {
            dfs(left, row + 1, column - (1 << (height - row - 1)));
        }
        if (right != null) {
            dfs(right, row + 1, column + (1 << (height - row - 1)));
        }
    }
}

复杂度分析

  • 时间复杂度: O ( h × 2 h ) O(h \times 2^h) O(h×2h),其中 h h h 是二叉树的高度。矩阵的行数 m m m 和列数 n n n 满足 m = h + 1 m = h + 1 m=h+1 n = 2 h + 1 − 1 n = 2^{h + 1} - 1 n=2h+11,输出二叉树的时间复杂度是 O ( m n ) = O ( h × 2 h ) O(mn) = O(h \times 2^h) O(mn)=O(h×2h)

  • 空间复杂度: O ( h ) O(h) O(h),其中 h h h 是二叉树的高度。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度。注意返回值不计入空间复杂度。

解法二

思路和算法

使用广度优先搜索输出二叉树时,使用两个队列分别存储待访问的结点和结点在矩阵中的位置,两个队列分别为结点队列和位置队列。初始时,将根结点入结点队列,将第 0 0 0 行第 n − 1 2 \dfrac{n - 1}{2} 2n1 列入位置队列。

每次将一个结点从结点队列出队,并将一个位置从位置队列出队,出队的位置即为出队的结点在矩阵中的位置。将当前结点值填入矩阵中的对应位置,然后计算出非空子结点在矩阵中的位置,将非空子结点和对应位置分别入两个队列。重复该过程直到所有结点遍历完毕,此时所有结点值都填入矩阵中的对应位置。

代码

class Solution {
    public List<List<String>> printTree(TreeNode root) {
        int height = getHeight(root);
        int m = height + 1;
        int n = (1 << m) - 1;
        List<List<String>> res = new ArrayList<List<String>>();
        for (int i = 0; i < m; i++) {
            List<String> row = new ArrayList<String>();
            for (int j = 0; j < n; j++) {
                row.add("");
            }
            res.add(row);
        }
        Queue<TreeNode> nodeQueue = new ArrayDeque<TreeNode>();
        Queue<int[]> locationQueue = new ArrayDeque<int[]>();
        nodeQueue.offer(root);
        locationQueue.offer(new int[]{0, (n - 1) / 2});
        while (!nodeQueue.isEmpty()) {
            TreeNode node = nodeQueue.poll();
            int[] location = locationQueue.poll();
            int row = location[0], column = location[1];
            res.get(row).set(column, String.valueOf(node.val));
            TreeNode left = node.left, right = node.right;
            if (left != null) {
                nodeQueue.offer(left);
                locationQueue.offer(new int[]{row + 1, column - (1 << (height - row - 1))});
            }
            if (right != null) {
                nodeQueue.offer(right);
                locationQueue.offer(new int[]{row + 1, column + (1 << (height - row - 1))});
            }
        }
        return res;
    }

    public int getHeight(TreeNode root) {
        int depth = -1;
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            depth++;
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return depth;
    }
}

复杂度分析

  • 时间复杂度: O ( h × 2 h ) O(h \times 2^h) O(h×2h),其中 h h h 是二叉树的高度。矩阵的行数 m m m 和列数 n n n 满足 m = h + 1 m = h + 1 m=h+1 n = 2 h + 1 − 1 n = 2^{h + 1} - 1 n=2h+11,输出二叉树的时间复杂度是 O ( m n ) = O ( h × 2 h ) O(mn) = O(h \times 2^h) O(mn)=O(h×2h)

  • 空间复杂度: O ( 2 h ) O(2^h) O(2h),其中 h h h 是二叉树的高度。空间复杂度主要是队列空间,队列内元素个数不超过二叉树的结点数,高度为 h h h 的二叉树中最多有 2 h + 1 − 1 2^{h + 1} - 1 2h+11 个结点。注意返回值不计入空间复杂度。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

oracle定位造成卡顿的SQL语句

先查询阻塞的会话号 select event,machine,sql_id,program,blocking_session from dba_hist_active_sess_history where SAMPLE_TIME between TO_TIMESTAMP (2021-08-25 15:25:00, YYYY-MM-DD HH24:MI:SS) and TO_TIMESTAMP (2021-08-25 15:30:00, YYYY-MM-DD HH24:MI:SS) and …

PolarDB-X、OceanBase、CockroachDB、TiDB二级索引写入性能测评

为什么要做这个测试 二级索引是关系型数据库相较于NoSQL数据库的一个关键差异。二级索引必须是强一致的&#xff0c;因此索引的写入需要与主键的写入放在一个事务当中&#xff0c;事务的性能是二级索引性能的基础。 目前市面上的分布式数据库中&#xff0c;从使用体验的角度看…

PCL点云处理之点云置平(拟合平面绕中心旋转到绝对水平)(二百二十七)

PCL点云处理之点云置平(绕中心旋转到绝对水平)(二百二十七) 一、什么是点云置平二、算法流程三、算法实现一、什么是点云置平 有时候,我们处理的点云平面并非位于水平面,而是位于某个任一三维平面上,而大多数算法又只能在水平面处理,或者水平面的点云处理是相对更简单…

互操作性(Interoperability)如何影响着机器学习的发展?

互操作性&#xff08;Interoperability&#xff09;&#xff0c;也称为互用性&#xff0c;即两个系统之间有效沟通的能力&#xff0c;是机器学习未来发展中的关键因素。对于银行业、医疗和其他生活服务行业&#xff0c;我们期望那些用于信息交换的平台可以在我们需要时无缝沟通…

弧形导轨的加工方式有哪些?

弧形导轨常用于流水线的加工或是机械化工业的生产中&#xff0c;运动的导轨呈弧形&#xff0c;可以连接起来形成其它形态也可以是单一的&#xff0c;使用弧形导轨后是可以提高工作效率的&#xff0c;比传统的生产模式要更加快速&#xff0c;所以在很多工厂或生产车间都有它的身…

前端开发新趋势:Web3 与虚拟现实的技术融合

在当今互联网技术日新月异的时代&#xff0c;Web技术也在不断地发展和变革。从前端开发的角度来看&#xff0c;新技术的涌现和旧技术的迭代让前端开发者们面临着前所未有的挑战和机遇。Web3 与虚拟现实&#xff08;VR&#xff09;的技术融合&#xff0c;正是当前前端开发领域的…

Spring Boot学习随笔- 文件上传和下载(在线打卡、附件下载、MultipartFile)

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十二章、文件上传、下载 文件上传 文件上传是指将文件从客户端计算机传输到服务器的过程。 上传思路 前端的上传页面&#xff1a;提交方式必须为post&#xff0c;enctype属性必须为multipart/form-data开发…

springboot云HIS医院信息管理系统源码

通过云HIS平台,可以减少医院投资,无需自建机房和系统,快速实现信息化服务。系统升级及日常维护服务有云平台提供,无需配备专业IT维护人员进行系统维护。 一、his系统和云his系统的区别 His系统和云his系统是两种不同的计算平台&#xff0c;它们在技术架构上存在很大的差异。下…

进阶之路:高级Spring整合技术解析

Spring整合 1.1 Spring整合Mybatis思路分析1.1.1 环境准备步骤1:准备数据库表步骤2:创建项目导入jar包步骤3:根据表创建模型类步骤4:创建Dao接口步骤5:创建Service接口和实现类步骤6:添加jdbc.properties文件步骤7:添加Mybatis核心配置文件步骤8:编写应用程序步骤9:运行程序 1.…

​Halcon机器视觉软件学习指南

引言 Halcon是由德国MVTec软件公司开发的一款领先的机器视觉软件&#xff0c;广泛应用于工业检测、图像分析、医疗图像处理等领域。对于大学生和初学者而言&#xff0c;学习Halcon不仅能够提升技术层面的能力&#xff0c;还能够增强未来的就业竞争力。本文将为您提供一个系统的…

东莞城市更新区域关注程度分析tiff数据,城市规划必备

基本信息. 数据名称: 东莞市城市更新区域关注程度分析数据 数据格式: tiff 时间版本&#xff1a;2022年 数据几何类型: 无 数据精度&#xff1a;区县 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据

【Anaconda】重装source 不生效,command not found 解决

事情是这样的&#xff0c;在Linux上安装anaconda的时候&#xff0c;由于一直需要同意其协议&#xff0c;因此在按enter 下一行时候出现过好几次翻过了&#xff0c;导致直接等于no了。&#xff08;实际上&#xff0c;按字母d可以实现翻页的功能&#xff0c;不需要一直enter了&am…

Ubuntu 常用命令之 awk 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 AWK是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。在Ubuntu系统下&#xff0c;AWK命令主要用于数据处理和生成报告。 AWK命令的参数主要有 -F&#xff1a;指定输入文件分隔符&#xff0c;FS变量就是指定输入字…

百年东芝“瞄准”汽车「芯」机遇

在汽车“新四化”大变革的驱动下&#xff0c;汽车半导体市场进入需求暴涨的新周期。 “智能电动汽车所需要的半导体种类和数量正在急剧增加。” 东芝电子分立器件应用技术部经理成栋表示&#xff0c;东芝电子正在加大汽车半导体市场的布局&#xff0c;从而满足汽车电动化、智能…

老师如何提高教育质量的问题

教育质量是学校教育的核心&#xff0c;也是衡量一个老师工作成果的重要标准。作为老师&#xff0c;我们应该时刻关注如何提高教育质量&#xff0c;以更好地促进学生的全面发展。 一、注重备课 备课是提高教育质量的基础。老师应该认真研究教材&#xff0c;了解学生的实际情况&…

ansible脚本-Playbook(一)

Playbook组成部分&#xff1a; task 任务&#xff1a;包含目标主机上执行的操作&#xff0c;使用模块定义这些操作&#xff0c;每个任务都是一个模块的调用Variables变量&#xff1a;存储和传递数据&#xff0c;变量可以自定义&#xff0c;可以在playbook当中定义为全局变量&a…

数据管理平台Splunk Enterprise本地部署结合内网穿透实现远程访问

文章目录 前言1. 搭建Splunk Enterprise2. windows 安装 cpolar3. 创建Splunk Enterprise公网访问地址4. 远程访问Splunk Enterprise服务5. 固定远程地址 前言 Splunk Enterprise是一个强大的机器数据管理平台&#xff0c;可帮助客户分析和搜索数据&#xff0c;以及可视化数据…

NCV8460ADR2G在汽车和工业应用中高压侧驱动如何破?

NCV8460ADR2G是一款完全保护的高压侧驱动器&#xff0c;可用于开关各种负载&#xff0c;如灯泡、电磁阀和其他致动器。该器件可以通过有源电流限制和高温关断针对过载情况进行内部保护。 诊断状态输出引脚提供了高温以及开关状态开路负载情况的数字故障指示。 特性&#xff1a;…

File.AppendAllText写入CSV时,打开表格出现乱码

发生乱码时&#xff1a; string time DateTime.Now.ToString("G");string filePath this.SavePath "\\产能记录.csv";string content time "," TodayNumber.ToString();File.AppendAllText(filePath, "\r\n" content);写入后&am…

c# winform chart 单个柱形设置

目前实现到第三张图形,有可以实现四张图形的请大佬帮助。 实现到第三张图的设置如下 private void Form1_Load(object sender, EventArgs e) {// 隐藏标题//chart1.Titles.Clear();// 隐藏图例chart1.Legends.Clear();// 隐藏 Y 轴的网格线和标签chart1.ChartAreas[0].AxisY.…