二叉树题目:翻转二叉树以匹配前序遍历

文章目录

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

题目

标题和出处

标题:翻转二叉树以匹配前序遍历

出处:971. 翻转二叉树以匹配前序遍历

难度

5 级

题目描述

要求

给定一个二叉树的根结点 root \texttt{root} root,二叉树中有 n \texttt{n} n 个结点,每个结点都有一个 1 \texttt{1} 1 n \texttt{n} n 之间的值且不同结点的值各不相同。另外给定一个由 n \texttt{n} n 个值组成的行程序列 voyage \texttt{voyage} voyage,表示预期的二叉树前序遍历结果。

通过交换结点的左右子树,可以翻转该二叉树中的任意结点。例如,翻转结点 1 \texttt{1} 1 的效果如下:

示例 0

请翻转最少的树中结点,使得二叉树的前序遍历与预期的遍历行程 voyage \texttt{voyage} voyage 相匹配

返回翻转的所有结点的值的列表。可以按任何顺序返回答案。如果不能,则返回列表 [-1] \texttt{[-1]} [-1]

示例

示例 1:

示例 1

输入: root = [1,2], voyage = [2,1] \texttt{root = [1,2], voyage = [2,1]} root = [1,2], voyage = [2,1]
输出: [-1] \texttt{[-1]} [-1]
解释:翻转结点无法令前序遍历匹配预期行程。

示例 2:

示例 2

输入: root = [1,2,3], voyage = [1,3,2] \texttt{root = [1,2,3], voyage = [1,3,2]} root = [1,2,3], voyage = [1,3,2]
输出: [1] \texttt{[1]} [1]
解释:翻转结点 1 \texttt{1} 1 交换结点 2 \texttt{2} 2 3 \texttt{3} 3,使得前序遍历可以匹配预期行程。

示例 3:

示例 3

输入: root = [1,2,3], voyage = [1,2,3] \texttt{root = [1,2,3], voyage = [1,2,3]} root = [1,2,3], voyage = [1,2,3]
输出: [] \texttt{[]} []
解释:前序遍历已经匹配预期行程,所以不需要翻转结点。

数据范围

  • 树中结点数目为 n \texttt{n} n
  • n = voyage.length \texttt{n} = \texttt{voyage.length} n=voyage.length
  • 1 ≤ n ≤ 100 \texttt{1} \le \texttt{n} \le \texttt{100} 1n100
  • 1 ≤ Node.val, voyage[i] ≤ n \texttt{1} \le \texttt{Node.val, voyage[i]} \le \texttt{n} 1Node.val, voyage[i]n
  • 树中的所有值各不相同
  • voyage \texttt{voyage} voyage 中的所有值各不相同

解法

思路和算法

二叉树的前序遍历的方法为:依次遍历根结点、左子树和右子树,对于左子树和右子树使用同样的方法遍历。对于每个结点,如果不翻转该结点,则遍历该结点之后依次遍历左子树和右子树,如果翻转该结点,则遍历该结点之后依次遍历右子树和左子树。由于题目要求翻转的结点数最少,因此只有当必须翻转结点的时候才翻转结点。当遍历到一个结点时,其子结点值和预期行程中的下一个值可能有以下情况。

  • 当前结点的左子结点为空或者左子结点值和预期行程中的下一个值相同,此时不需要翻转当前结点。

  • 当前结点的左子结点不为空且左子结点值和预期行程中的下一个值不同,如果不翻转当前结点则下一个访问的结点是左子结点,无法匹配预期行程,此时需要翻转当前结点。翻转当前结点之后不能保证匹配预期行程,而是需要访问原右子结点,判断当前结点的原右子结点值是否和预期行程中的下一个值相同,可能有以下两种情况。

    • 如果原右子结点值和预期行程中的下一个值相同,则翻转当前结点之后,原右子结点匹配预期行程,继续遍历判断其余的结点是否匹配预期行程。

    • 如果原右子结点值和预期行程中的下一个值不同,则翻转当前结点之后,仍无法匹配预期行程。由于当前结点无论是否翻转都无法匹配预期行程,因此无法通过翻转二叉树中的结点匹配预期行程。

根据上述分析,可以在二叉树前序遍历的基础上做修改,得到翻转的结点值列表。从根结点开始前序遍历二叉树,遍历过程中维护翻转的结点值列表并维护状态值记录是否存在翻转方案(不存在翻转方案表示无法通过翻转二叉树中的结点匹配预期行程),初始时翻转的结点值列表为空,状态值为存在翻转方案,具体做法如下。

  1. 如果当前结点为空或者状态值为不存在翻转方案,则直接返回。

  2. 如果当前结点值和预期行程中的当前值不同,则将翻转的结点值列表清空然后将 − 1 -1 1 加入翻转的结点值列表,并将状态值设为不存在翻转方案,然后返回。

  3. 根据当前结点的左右子结点,判断当前结点是否需要翻转,并决定遍历左右子树的顺序。

    • 如果当前结点的左子结点为空或者左子结点值和预期行程中的下一个值相同,则不需要翻转当前结点,依次对左子树和右子树前序遍历。

    • 否则,需要翻转当前结点,将当前结点值加入翻转的结点值列表,依次对右子树和左子树前序遍历。

遍历结束之后,即可得到翻转的结点值列表。如果存在翻转方案,则列表中的元素为所有需要翻转的结点值,特别地,当列表为空时,表示原二叉树已经匹配预期行程因此不需要翻转任何结点;如果不存在翻转方案,则列表中只有一个元素 − 1 -1 1

代码

class Solution {List<Integer> flips;int[] voyage;int n;int index;boolean possible;public List<Integer> flipMatchVoyage(TreeNode root, int[] voyage) {this.flips = new ArrayList<Integer>();this.voyage = voyage;this.n = voyage.length;this.index = 0;this.possible = true;preorder(root);return flips;}public void preorder(TreeNode node) {if (node == null || !possible) {return;}if (node.val != voyage[index]) {flips.clear();flips.add(-1);possible = false;return;}index++;TreeNode left = node.left, right = node.right;if (left == null || left.val == voyage[index]) {preorder(left);preorder(right);} else {flips.add(node.val);preorder(right);preorder(left);}}
}

复杂度分析

  • 时间复杂度: 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/212057.html

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

相关文章

Redis--13--缓存一致性问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 缓存一致性问题1、先更新缓存&#xff0c;再更新DB方案二&#xff1a;先更新DB&#xff0c;再更新缓存方案三&#xff1a;先删缓存&#xff0c;再写数据库推荐1&…

【c】杨辉三角

下面介绍两种方法 1.利用上面性质的第五条&#xff0c;我们可以求各行各列的组合数 2.利用上面性质的第7条&#xff0c;我们可以用数组完成 下面附上代码 1. #include<stdio.h> void fact(int n ,int m )//求组合数 {long long int sum11;long long int sum21;int a…

C#中GDI+图形图像技术(Graphics类、Pen类、Brush类)

目录 一、创建Graphics对象 1.创建Pen对象 2.创建Brush对象 &#xff08;1&#xff09;SolidBrush类 &#xff08;2&#xff09;HatchBrush类 ​​​​​​​&#xff08;3&#xff09;LinerGradientBrush类 用户界面上的窗体和控件非常有用&#xff0c;且引人注目&#…

家政小程序源码,师傅竞价接单

家政预约上门服务小程序开发方案&#xff0c;php开发语言&#xff0c;前端是uniapp&#xff0c;有成品源码&#xff0c;可以二开&#xff0c;可以定制。 一家政小程序用户端功能&#xff1a;服务分类、在线预约、在线下单。 师傅端&#xff1a;在线接单&#xff0c;竞价&…

zabbix分布式监控平台从IPV4切换到IPV6之监控主机切换

现在有一套监控了海量服务器的zabbix分布式监控平台需整体在线从IPV4切换到IPV6&#xff0c;不能影响其原有的定制监控及视图。本文讲解了切换的第一步--监控主机切换。 一、zabbix分布式监控平台平台架构 本套zabbix分布式监控平台是一个多代理服务器分布式部署的典型传统架构…

rocketMQ介绍

作用 流量削峰系统解耦 功能 普通消息 同步消息异步消息事务消息顺序消息延迟消息订阅与发布消息过滤消息消费重试死信队列...... 架构设计 1个broker是1台实例每个broker都有从节点&#xff0c;便于做故障转移每个broker对应一个文件&#xff0c;存储数据&#xff1f;还是…

基于单片机设计的自动门控制系统

一、前言 自动门控制系统是一种智能化的应用&#xff0c;能够根据人体接近信号自动完成门的打开和关闭操作。在传统的门控系统中&#xff0c;通常需要人手动进行门的开启和关闭&#xff0c;不仅费时费力&#xff0c;还不够智能高效。 本项目采用了STC89C52作为主控芯片&#…

【高数:1 映射与函数】

【高数&#xff1a;1 映射与函数】 例2.1 绝对值函数例2.2 符号函数例2.3 反函数表示例2.4 双曲正弦sinh&#xff0c;双曲余弦cosh&#xff0c;双曲正切tanh 参考书籍&#xff1a;毕文斌, 毛悦悦. Python漫游数学王国[M]. 北京&#xff1a;清华大学出版社&#xff0c;2022. 例2…

1.1美术理论基础

一、光影 物体呈现在人们眼前的时候&#xff0c;不同的受光面其明暗变化以及物体的影子。 1.什么是黑白灰 在美术中黑白灰指亮面、灰面、暗面&#xff0c;属于素描的三大面&#xff0c;主要体验一个物体的整体寿光过程。普遍存在于各种艺术和设计领域。黑白灰作品的出现&#x…

一文搞懂系列——你真的了解如何生成动态库了吗?

引言 动态库的编译&#xff0c;这有什么难度&#xff0c;这不是手到擒来的事情吗&#xff1f;无非不就是&#xff1a; gcc -FPIC -shared -o libxxx.so *.o *.c 我若是提出这些需求场景&#xff0c;阁下又如何应对呢&#xff1f; 动态库A依赖其他部分提供的能力。但是却不…

LinkedList详解

LinkedList详解 LinkedList是List接口的一个主要的实现类之一&#xff0c;基于链表的实现。以java8为例来了解一下LinkedList的源码实现 继承关系 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>,…

第十五届蓝桥杯模拟赛B组(第二期)C++

前言&#xff1a; 第一次做蓝桥模拟赛的博客记录&#xff0c;可能有很多不足的地方&#xff0c;现在将第十五届蓝桥杯模拟赛B组&#xff08;第二期&#xff09;的题目与代码与大家进行分享&#xff0c;我是用C做的&#xff0c;有好几道算法题当时自己做的也是一脸懵&#xff0c…

DELL EMC unity 存储系统日志收集方法

对于一些非简单的硬件故障&#xff0c;解决故障最有效、最快速的方法就是收集日志&#xff0c;而不是瞎搞。常见的乱搞方法就是 1. reimage系统‘ 2. 更换控制器&#xff1b;3&#xff0c; 重启。 本文详细介绍了图形界面GUI和命令行CLI下如何收集DELL EMC Unity日志的方法和常…

WPS导出的PDF比较糊,和原始的不太一样,将带有SVG的文档输出为PDF

一、在WPS的PPT中 你直接输出PDF可能会导致一些问题&#xff08;比如照片比原来糊&#xff09;/ 或者你复制PPT中的图片到AI中类似的操作&#xff0c;得到的照片比原来糊&#xff0c;所以应该选择打印-->高级打印 然后再另存为PDF 最后再使用AI打开PDF文件再复制到你想用…

挑选数据可视化工具:图表类型、交互功能与数据安全

作为一名数据分析师&#xff0c;我经常需要使用各种数据可视化工具来将数据以直观、清晰的方式呈现出来&#xff0c;以便更好地理解和分析。在市面上的众多可视化工具中&#xff0c;我根据实际需求和项目特点进行选择。本文将从以下几个角度对市面上的数据可视化工具进行对比&a…

flutter开发实战-轮播Swiper更改Custom_layout样式中Widget层级

flutter开发实战-轮播Swiper更改Custom_layout样式中Widget层级 在之前的开发过程中&#xff0c;需要实现卡片轮播效果&#xff0c;但是卡片轮播需要中间大、两边小一些的效果&#xff0c;这里就使用到了Swiper。具体效果如视频所示 添加链接描述 这里需要的效果是中间大、两边…

安装postgresql驱动及python使用pyodbc指定postgresql驱动调用postgresql

注&#xff1a;Python解释器版本(32位/64位)和postgresql驱动版本(32位/64位)需一致。 一、安装postgresql驱动 https://www.postgresql.org/ftp/odbc/versions/msi/ &#xff08;1&#xff09;32位&#xff1a; &#xff08;2&#xff09;64位&#xff1a; 双击安装。全程默…

高精度加法,减法,乘法,除法(上)(C语言)

前言 加&#xff0c;减&#xff0c;乘&#xff0c;除这些运算我们自然信手捏来&#xff0c;就拿加法来说&#xff0c;我们要用c语言编程算ab的和&#xff0c;只需让sum ab即可&#xff0c;可是这是局限的&#xff0c;我们都知道int的表示的最大值为2147483647&#xff08;32位…

2023.12.3 分布式SQL查询引擎-Presto

目录 目录 1.Prosto简介 Apache Hadoop-MapReduce Apache Hive 2.Presto的优缺点 3.个人自用启动服务 个人自用启动服务 3.Presto的架构 4.presto和hive的区别 5.presto优化 6.Presto-内存调优 1.Prosto简介 Apache Hadoop-MapReduce 优点&#xff1a;统一、通用、简…