二叉树题目:奇偶树

news2025/1/8 4:13:29

文章目录

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

题目

标题和出处

标题:奇偶树

出处:1609. 奇偶树

难度

4 级

题目描述

要求

如果一个二叉树满足下述条件,则称为奇偶树

  • 二叉树根结点所在层下标为 0 \texttt{0} 0,根结点的子结点所在层下标为 1 \texttt{1} 1,根结点的孙结点所在层下标为 2 \texttt{2} 2,依此类推。
  • 偶数下标层上的所有结点的值都是整数,从左到右按顺序严格递增
  • 奇数下标层上的所有结点的值都是整数,从左到右按顺序严格递减

给定二叉树的根结点,如果二叉树为奇偶树,则返回 true \texttt{true} true,否则返回 false \texttt{false} false

示例

示例 1:

示例 1

输入: root   =   [1,10,4,3,null,7,9,12,8,6,null,null,2] \texttt{root = [1,10,4,3,null,7,9,12,8,6,null,null,2]} root = [1,10,4,3,null,7,9,12,8,6,null,null,2]
输出: true \texttt{true} true
解释:每一层的结点值分别是:
0 \texttt{0} 0 层: [1] \texttt{[1]} [1]
1 \texttt{1} 1 层: [10,4] \texttt{[10,4]} [10,4]
2 \texttt{2} 2 层: [3,7,9] \texttt{[3,7,9]} [3,7,9]
3 \texttt{3} 3 层: [12,8,6,2] \texttt{[12,8,6,2]} [12,8,6,2]
由于第 0 \texttt{0} 0 层和第 2 \texttt{2} 2 层上的结点值都是奇数且严格递增,而第 1 \texttt{1} 1 层和第 3 \texttt{3} 3 层上的结点值都是偶数且严格递减,因此这是一个奇偶树。

示例 2:

示例 2

输入: root   =   [5,4,2,3,3,7] \texttt{root = [5,4,2,3,3,7]} root = [5,4,2,3,3,7]
输出: false \texttt{false} false
解释:每一层的结点值分别是:
0 \texttt{0} 0 层: [5] \texttt{[5]} [5]
1 \texttt{1} 1 层: [4,2] \texttt{[4,2]} [4,2]
2 \texttt{2} 2 层: [3,3,7] \texttt{[3,3,7]} [3,3,7]
2 \texttt{2} 2 层上的结点值不满足严格递增的条件,所以这不是一个奇偶树。

示例 3:

示例 3

输入: root   =   [5,9,1,3,5,7] \texttt{root = [5,9,1,3,5,7]} root = [5,9,1,3,5,7]
输出: false \texttt{false} false
解释:第 1 \texttt{1} 1 层上的结点值应为偶数。

数据范围

  • 树中结点数目在范围 [1,   10 5 ] \texttt{[1, 10}^\texttt{5}\texttt{]} [1, 105]
  • 1 ≤ Node.val ≤ 10 6 \texttt{1} \le \texttt{Node.val} \le \texttt{10}^\texttt{6} 1Node.val106

解法一

思路和算法

为了判断二叉树是否为奇偶树,需要判断以下条件。

  • 对于任意结点,结点值与结点所在层数的奇偶性不同。

  • 偶数层的结点从左到右严格单调递增,奇数层的结点从左到右严格单调递减。

由于判断奇偶树的依据是每一层结点都要符合奇偶树的条件,因此可以使用层序遍历实现。

从根结点开始依次遍历每一层的结点,同一层的结点的遍历顺序为从左到右。在层序遍历的过程中需要区分不同结点所在的层,确保每一轮访问的结点为同一层的全部结点。遍历每一层结点之前首先得到当前层的结点数,即可确保每一轮访问的结点为同一层的全部结点。

每次访问结点时,将待访问的结点出队列,判断是否符合奇偶树的条件。

  • 如果结点值与结点所在层数的奇偶性相同,则二叉树不是奇偶树。

  • 如果当前访问的结点不是当前层的最后一个结点,则此时的队首元素即为下一个结点(注意当前结点已经出队列),比较当前结点值与下一个结点值的大小。如果当前层是偶数层且当前结点值大于等于下一个结点值,或者当前层是奇数层且当前结点值小于等于下一个结点值,则二叉树不是奇偶树。

遍历结束之后,如果没有发现不符合奇偶树的条件的情况,则二叉树为奇偶树。

代码

class Solution {
    public boolean isEvenOddTree(TreeNode root) {
        int level = -1;
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            level++;
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.poll();
                if (node.val % 2 == level % 2) {
                    return false;
                }
                if (i < size - 1) {
                    int nextVal = queue.peek().val;
                    if ((level % 2 == 0 && node.val >= nextVal) || (level % 2 == 1 && node.val <= nextVal)) {
                        return false;
                    }
                }
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
        }
        return true;
    }
}

复杂度分析

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

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

解法二

思路和算法

也可以使用深度优先搜索判断二叉树是否为奇偶数。具体做法是使用前序遍历,依次访问二叉树的根结点、左子树和右子树,由于前序遍历满足同一层结点被访问的顺序为从左到右,因此可以在前序遍历过程中判断二叉树是否符合奇偶树的条件。遍历过程中需要维护二叉树每一层的最右侧结点值。

对于每个结点,判断是否符合奇偶树的条件。

  • 如果结点值与结点所在层数的奇偶性相同,则二叉树不是奇偶树。

  • 如果当前层已经有访问过的结点,则得到上一个结点值,即当前层已经访问的最右侧结点值,比较上一个结点值与当前结点值的大小。如果当前层是偶数层且上一个结点值大于等于当前结点值,或者当前层是奇数层且上一个结点值小于等于当前结点值,则二叉树不是奇偶树。

在访问每个结点之后,将当前层的最右侧结点值设为当前结点值。

遍历结束之后,如果没有发现不符合奇偶树的条件的情况,则二叉树为奇偶树。

代码

class Solution {
    List<Integer> rightmost = new ArrayList<Integer>();

    public boolean isEvenOddTree(TreeNode root) {
        return dfs(root, 0);
    }

    public boolean dfs(TreeNode node, int level) {
        if (node.val % 2 == level % 2) {
            return false;
        }
        if (level < rightmost.size()) {
            int prev = rightmost.get(level);
            if ((level % 2 == 0 && prev >= node.val) || (level % 2 == 1 && prev <= node.val)) {
                return false;
            }
            rightmost.set(level, node.val);
        } else {
            rightmost.add(node.val);
        }
        return (node.left == null || dfs(node.left, level + 1)) && (node.right == null || dfs(node.right, level + 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.coloradmin.cn/o/1037887.html

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

相关文章

【深度学习】BLIP: 用于统一的视觉-语言理解和生成的引导式语言图像预训练

BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation BLIP&#xff1a;用于统一的视觉-语言理解和生成的引导式语言图像预训练 论文&#xff1a;https://arxiv.org/abs/2201.12086 代码&#xff1a;https://github.…

springboot对接rabbitmq并且实现动态创建队列和消费

背景 1、对接多个节点上的MQ&#xff08;如master-MQ&#xff0c;slave-MQ&#xff09;&#xff0c;若读者需要自己模拟出两个MQ&#xff0c;可以部署多个VM然后参考 docker 安装rabbitmq_Steven-Russell的博客-CSDN博客 2、队列名称不是固定的&#xff0c;需要接受外部参数&…

【LRU】一文让你弄清 Redis LRU 页面置换算法

Q&#xff1a;一天同事问&#xff0c;我放在 redis 中的 key&#xff0c;为什么有时候过一段时间数据就没有了&#xff0c;我并没有设置过期时间呀&#xff1f;&#xff1f;&#x1f633;&#x1f633; A&#xff1a;你的 redis 淘汰策略是什么样的&#xff0c;这个 key 可能是…

dirname - return directory part of PATH.

用Visual Studio 2022开发Linux程序, 用ssh连接 函数单元测试 下载glibc解压到E:\library\GNU\glibc-2.38 mzhDESKTOP-GITL67P:~$ sudo /etc/init.d/ssh start * Starting OpenBSD Secure Shell server sshd …

【Spring】-Bean的作用域和生命周期

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Framework】 主要内容&#xff1a;Lombok的使用&#xff0c;Bean作用域的分类和修改。Singleton、Prototype。spring的执行流程&#xff0c;Bean的生命历程。 文章目录 一、Bea…

树莓派+墨水屏 = DIY一个超慢速电影播放器

安装电子墨水屏这里使用了 Waveshare 的一款墨水屏&#xff0c;带驱动板。将驱动板插入树莓派的 GPIO 即完成屏幕和树莓派的连接。驱动这个屏幕需要启用树莓派的 SPI 接口。运行 sudo raspi-config 进入配置工具来启用 SPI 运行python例程 安装函数库 sudo apt-get update su…

指针笔试题详解

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2.指针题写出下列程序的结…

Unity Windows上Inspector界面黑屏无法显示

问题描述&#xff1a;在Windows上Unity 打开工程Inspector显示黑色&#xff0c;不可用。如下图&#xff1a; 可能的问题。 Unity 设置Windows上默认渲染方式显卡不支持。 解决方案&#xff1a; 一、换一个好一点显卡 二、如下图&#xff1a;

Transformer的上下文学习能力

《Uncovering mesa-optimization algorithms in Transformers》 论文链接&#xff1a;https://arxiv.org/abs/2309.05858 为什么 transformer 性能这么好&#xff1f;它给众多大语言模型带来的上下文学习 (In-Context Learning) 能力是从何而来&#xff1f;在人工智能领域里&…

实验室安全教育与考试

目录 我的错题&#xff08;2个&#xff09;新知识题目&#xff08;10个&#xff09;刚开始不太理解的题目&#xff08;10个&#xff09;写在最后&#xff08;免责声明&#xff09; 我的错题&#xff08;2个&#xff09; 18.发生电气火灾时可以使用的灭火设备包括&#xff1a;&…

SAP Service服务重注册技术手册

当SAP服务被卸载后,或SAP虚拟机整机copy后(可能还需要涉及主机名更改),需要对SAP服务重注册。 在路径 \sapmnt\<SID>\ DVEBMGS00\exe下使用程序sapstartsrv.exe来卸载、安装SAP服务: 其中<SID>、NR参考Service中需要卸载的服务名(卸载后,Services列表中的SA…

【UE 粒子练习】08——LOD概述

目录 概念 应用举例 一、检查当前粒子系统中是否设置了LOD 二、添加LOD 三、LOD设置&#xff08;单个粒子发射器&#xff09; 四、LOD设置&#xff08;多个粒子发射器&#xff09; 概念 在 Unreal Engine 中&#xff0c;LOD&#xff08;Level of Detail&#xff0c;细…

Kubernetes 学习总结(37)—— Kubernetes 之 CoreDNS 企业级应用

前言 IP 地址会有变更&#xff0c;程序配置IP地址&#xff0c;所有涉及到此IP的地方都需要改变&#xff0c;对运维和研发都不友好。IP不容易被记住。引入域名来替换 IP&#xff0c;这样业务使用唯一标识域名&#xff0c;域名可以通过 DNS 服务器解析成 IP 供业务三层通信使用。…

时间复杂度、空间复杂度

一、时间复杂度 1、概念 时间复杂度&#xff1a;计算的是当一个问题量级增加的时间&#xff0c;时间增长的趋势&#xff1b; O&#xff08;大O表示法&#xff09;&#xff1a;渐进的时间复杂度 2、举例 ① 以下 for 循环的时间复杂度&#xff1a;O(1 3n) O(n) 去掉常数…

rom修改----安卓系列机型如何内置app 如何选择so文件内置

系统内置app的需求 在与各工作室对接中操作单中&#xff0c;很多需要内置客户特定的有些app到系统里&#xff0c;这样方便客户刷入固件后直接调用。例如内置apk 去开机引导 去usb调试 默认开启usb安全设置等等。那么很多app内置有不同的反应。有的可以直接内置。有的需要加so…

(十三)VBA常用基础知识:编程时各种常用操作之设值,取值,活动窗口设定

cell里设置内容的两个写法 Sub test() Range("A1").Value "帅哥" Cells(1, 2).Value "帅哥 too" End Sub2.cell里内容的取得 Sub test() Range("A1").Value "帅哥" Cells(1, 2).Value "帅哥 too" a Range(…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切(ROI)功能(C#)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切&#xff08;ROI&#xff09;功能&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的图像剪切&#xff08;ROI&#xff09;功能的技术背景CameraExplorer如何使用图像剪切&#xff08;ROI&#xff09;功…

[nodejs]NVM使用指南

安装 官网链接 使用 # 版本号 nvm version# 显示node是运行在32位还是64位。 nvm arch# 显示已安装的列表 nvm list nvm ls# 使用制定版本node。可指定32/64位 nvm use [version] [arch]# 显示可安装的所有版本 nvm list available# 安装最新版本 nvm install latest# 安装指…

【Linux】系统编程简单线程池(C++)

目录 【1】线程池概念 【1.1】线程池 【1.2】线程池的应用场景 【1.3】线程池的种类 【1.4】线程池示例 【2】线程池代码 【1】线程池概念 【1.1】线程池 一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&a…

【新书推荐】用户画像:了解用户,助力企业成长 ——《用户画像:平台构建与业务实践》

文章目录 〇、引子一、什么是用户画像二、用户画像的优势三、如何实现用户画像四、用户画像应用中的问题五、总结新书推荐 —— 《用户画像&#xff1a;平台构建与业务实践》内容简介目录 〇、引子 在当今市场竞争激烈的时代&#xff0c;了解用户需求、提高用户体验已成为企业…