二叉树题目:二叉树着色游戏

news2024/10/6 14:30:05

文章目录

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

题目

标题和出处

标题:二叉树着色游戏

出处:1145. 二叉树着色游戏

难度

6 级

题目描述

要求

两位玩家参与二叉树着色游戏。给定二叉树的根结点 root \texttt{root} root,以及树中的结点数目 n \texttt{n} n n \texttt{n} n 是奇数且每个结点的值从 1 \texttt{1} 1 n \texttt{n} n 各不相同。

初始时,第一位玩家选择一个值 x \texttt{x} x,满足 1 ≤ x ≤ n \texttt{1} \le \texttt{x} \le \texttt{n} 1xn,第二位玩家选择一个值 y \texttt{y} y,满足 1 ≤ y ≤ n \texttt{1} \le \texttt{y} \le \texttt{n} 1yn y ≠ x \texttt{y} \ne \texttt{x} y=x。第一位玩家将值为 x \texttt{x} x 的结点涂上红色,第二位玩家将值为 y \texttt{y} y 的结点涂上蓝色。

之后从第一位玩家开始,两位玩家轮流操作。每一轮,玩家选择自己颜色的结点(第一位玩家选择红色,第二位玩家选择蓝色),将所选结点的一个未涂色的相邻结点(左子结点、右子结点或者父结点)涂上颜色。

当且仅当一位玩家无法按照该规则选择结点时,该玩家必须跳过当前轮次。如果两位玩家都跳过当前轮次,游戏结束,涂色结点更多的玩家是获胜方。

你是第二位玩家。如果可能选择一个 y \texttt{y} y 确保你赢得游戏,返回 true \texttt{true} true。如果不可能,返回 false \texttt{false} false

示例

示例 1:

示例 1

输入: root   =   [1,2,3,4,5,6,7,8,9,10,11],   n   =   11,   x   =   3 \texttt{root = [1,2,3,4,5,6,7,8,9,10,11], n = 11, x = 3} root = [1,2,3,4,5,6,7,8,9,10,11], n = 11, x = 3
输出: true \texttt{true} true
解释:第二位玩家可以选择值为 2 \texttt{2} 2 的结点。

示例 2:

输入: root   =   [1,2,3],   n   =   3,   x   =   1 \texttt{root = [1,2,3], n = 3, x = 1} root = [1,2,3], n = 3, x = 1
输出: false \texttt{false} false

数据范围

  • 树中结点数目是 n \texttt{n} n
  • 1 ≤ x ≤ n ≤ 100 \texttt{1} \le \texttt{x} \le \texttt{n} \le \texttt{100} 1xn100
  • n \texttt{n} n 是奇数
  • 1 ≤ Node.val ≤ n \texttt{1} \le \texttt{Node.val} \le \texttt{n} 1Node.valn
  • 树中的所有值各不相同

解法

思路和算法

由于二叉树中的结点数目是 n n n,每个结点的值从 1 1 1 n n n 各不相同, 1 ≤ x ≤ n 1 \le x \le n 1xn,因此二叉树中存在唯一的值为 x x x 的结点,该结点称为结点 x x x

首先使用深度优先搜索在二叉树中定位到结点 x x x,结点 x x x 将二叉树中的其余 n − 1 n - 1 n1 个结点分成三个部分:结点 x x x 的左子树、结点 x x x 的右子树和其余结点,每个部分各为一个连通区域,不同部分之间不连通,每个部分的结点数最少为 0 0 0,最多为 n − 1 n - 1 n1,三个部分的结点数总和为 n − 1 n - 1 n1

根据游戏规则,每一位玩家在分别选择第一个涂色的结点之后,每次选择涂色的结点都必须和己方已经涂色的结点相邻,因此同一位玩家涂色的结点一定总是相连的。由于结点 x x x 被第一位玩家涂色,因此第二位玩家选择的结点 y y y 一定属于三个部分之一,且当第二位玩家选择结点 y y y 之后,只能在同一个部分继续涂色。

第二位玩家为了赢得游戏,选择的结点 y y y 应该使得己方可以涂色的结点数最多,因此结点 y y y 应该位于结点数最多的一个部分。只要结点 y y y 和结点 x x x 相邻,第二位玩家即可确保结点 y y y 所在的部分的所有结点都可以由第二位玩家涂色。为了使得结点 y y y 和结点 x x x 相邻,结点 y y y 应为结点 x x x 的左子结点、右子结点或者父结点,由于结点 y y y 所在的部分的结点数一定大于 0 0 0,因此结点 y y y 不为空。

除了结点 y y y 所在的部分以外,其余结点都由第一位玩家涂色,因此判断第二位玩家是否可以赢得游戏的依据是结点 y y y 所在的部分的结点数是否大于其余结点数总和。由于二叉树中的结点数目 n n n 是奇数,因此第二位玩家可以赢得游戏等价于结点 y y y 所在的部分的结点数至少为 n + 1 2 \dfrac{n + 1}{2} 2n+1

由于第二位玩家选择的结点 y y y 应该位于结点数最多的一个部分,因此只需要判断三个部分的结点数中的最大值是否至少为 n + 1 2 \dfrac{n + 1}{2} 2n+1,即可知道第二位玩家是否可以赢得游戏。

计算三个部分的结点数的方法为:对结点 x x x 的左子树和右子树分别使用深度优先搜索计算结点数,左子树和右子树的结点数分别记为 leftCount \textit{leftCount} leftCount rightCount \textit{rightCount} rightCount,剩下的一个部分的结点数为 n − 1 − leftCount − rightCount n - 1 - \textit{leftCount} - \textit{rightCount} n1leftCountrightCount。只要有一个部分的结点数至少为 n + 1 2 \dfrac{n + 1}{2} 2n+1,则返回 true \text{true} true,否则返回 false \text{false} false

代码

class Solution {
    TreeNode xNode;

    public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
        search(root, x);
        int threshold = (n + 1) / 2;
        int leftCount = countSubtreeNodes(xNode.left);
        if (leftCount >= threshold) {
            return true;
        }
        int rightCount = countSubtreeNodes(xNode.right);
        if (rightCount >= threshold) {
            return true;
        }
        int remain = n - 1 - leftCount - rightCount;
        return remain >= threshold;
    }

    public void search(TreeNode node, int x) {
        if (xNode != null || node == null) {
            return;
        }
        if (node.val == x) {
            xNode = node;
            return;
        }
        search(node.left, x);
        search(node.right, x);
    }

    public int countSubtreeNodes(TreeNode node) {
        if (node == null) {
            return 0;
        }
        return 1 + countSubtreeNodes(node.left) + countSubtreeNodes(node.right);
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。定位到结点 x x x 和计算二叉树每个部分的结点数的过程中,每个结点最多被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)

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

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

相关文章

亿发:数据无缝整合,实时洞察业务——深入分析ERP系统的四大业财一体化优势

"业务财务一体化"是企业数字化的核心议题之一。在业务运作过程中,财务记账能够实现自动、实时化。这也是传统企业资源计划(ERP)系统的主要价值,实现业务流、信息流和资金流的无缝整合,同时满足企业对业务风险…

深入解析Spring Boot集成MyBatis的多种方式

文章目录 1. 引言2. 传统的XML配置方式2.1 引入依赖2.2 配置数据源和MyBatis2.3 编写Mapper接口和XML映射文件2.4 使用Mapper 3. 注解配置方式3.1 引入依赖3.2 配置数据源和MyBatis3.3 编写Mapper接口3.4 使用Mapper 4. MyBatis动态SQL4.1 使用XML配置方式4.2 使用注解配置方式…

laravel的安装

laravel的安装(Composer小皮) Composer的安装 windows下安装 https://getcomposer.org/Composer-Setup.exe 修改镜像 阿里云: composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 华为云: compos…

时序分解 | Matlab实现DBO-VMD基于蜣螂优化算法优化VMD变分模态分解时间序列信号分解

时序分解 | Matlab实现DBO-VMD基于蜣螂优化算法优化VMD变分模态分解时间序列信号分解 目录 时序分解 | Matlab实现DBO-VMD基于蜣螂优化算法优化VMD变分模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.利用蜣螂优化算法优化VMD中的参数k、a&…

带你了解OpenCV4工业缺陷检测的六种方法

文章目录 OpenCV4工业缺陷检测的六种方法机器视觉缺陷检测1. 工业上常见缺陷检测方法方法一:基于简单二值图像分析实现划痕提取,效果如下:方法二:复杂背景下的图像缺陷分析,基于频域增强的方法实现缺陷检测&#xff0c…

【工作流Activiti】Activiti流程操作

1、流程定义 我们定义一个请假流程 1.1、新建模型 1.2、开始节点 1.3、任务节点 1.4、结束节点 1.5、设置节点属性 指定标签名称:张三审批,节点任务负责人:zhangsan 指定标签名称:李四审批,节点任务负责人&#xf…

【稳定检索|投稿优惠】2024年公共服务、健康与医药国际会议(ICPSHM 2024)

2024年公共服务、健康与医药国际会议(ICPSHM 2024) 2024 International Conference on Public Services, Health, and Medicine(ICPSHM) 一、【会议简介】 ​2024年公共服务、健康与医药国际会议(ICPSHM 2024)将于三亚这片美丽的海滨城市盛大召开。我们诚…

【JAVA基础(对象和封装以及构造方法)】----第四天

对象和封装以及构造方法 面向对象和面向过程面向过程面向对象 类与对象及其使用定义类创建一个对象,操作类补充(成员变量和局部变量) private 修饰类 封装练习编写类编写测试输出结果 面向对象和面向过程 面向过程 在了解面向对象之前先来了…

线上BUG引起思考:package.json 中的 ^~ 该保留吗?

一、写在前面 一次线上项目 bug,引发了关于 package.json 中的 ^~ 是否该保留?保留可能引发的后果?以及如何在版本更新便利和版本更稳定中取舍的思考?这个 bug 是由于线上部署打包时,自己下载了最新依赖,于…

如何本地搭建Zblog网站并通过内网穿透将个人博客发布到公网

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站…

12.DHCP

DHCP 用户上网的时候,会从网卡发一个DHCP请求,是一个广播报文255.255.255.255,源地址是0.0.0.0 服务器得到请求后,返回给客户端一个地址 1.在路由器开启DHCP功能 2.配置地址池 3.指明给用户分配的网段…

制造企业MES管理系统可以和AI结合应用吗

在当今的数字化时代,人工智能AI和MES生产管理系统的结合将成为制造企业发展的重要趋势。这种结合可以为制造企业带来许多优势,如提高生产效率、降低成本、优化资源利用等。本文将探讨MES管理系统和AI的结合以及它们在制造企业中的应用,并分析…

Gateway网关-路由的过滤器配置

目录 一、路由过滤器 GatewayFilter 1.1 过滤器工厂GatewayFilterFactory 1.2 案例给所有进入userservice的请求添加一个请求头 Truthitcastis freaking awesome! 1.3 案例给所有请求添加一个请求头 Truthitcastis freaking awesome! 一、路由过滤器 …

鸿海携手Porotech共同开启Micro LED新篇章 | 百能云芯

近日,鸿海集团决定进一步强化其在Micro LED(微发光二极体)技术领域的实力。为此,鸿海宣布将与英国半导体企业Porotech展开战略合作,旨在共同开发MicroLED微显示器,并在AR(扩增实境)应…

Python学习之复习MySQL-Day8(事务)

目录 文章声明⭐⭐⭐让我们开始今天的学习吧!事务简介事务操作模拟转账操作开启事务提交事务回滚事务查看/设置事务提交方法实例演示 事务四大特性并发事务问题分类 事务隔离级别分类查看/设置事务隔离级别实例演示 文章声明⭐⭐⭐ 该文章为我(有编程语…

记录 | C++头文件中 <> 和 ““ 的区别

C 头文件中 <> 和 “” 的区别 #include <cstdio> #include "hello.h"int main(){printf("hello world!");return 0; }● <cstdio> 这种形式表示不要在当前目录下进行搜索&#xff0c;只在系统目录里搜索&#xff1b; ● "hello.h…

【网络安全】-Linux操作系统—操作系统发展历史与Linux

文章目录 操作系统发展历史初期的操作系统分时操作系统个人计算机操作系统 Linux的诞生UNIX与GNU项目Linux内核的创建 Linux的特点开放源代码多样性社区支持 Linux的应用服务器和超级计算机嵌入式系统桌面系统 总结 操作系统发展历史 操作系统&#xff08;Operating System&am…

Linux部署Nacos注册中心结合内网穿透实现远程访问UI管理界面

文章目录 1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Plik8. 结语 Nacos是阿里开放的一款中间件,也是一款服务注册中心&#xff0c;它主要提供三种功能&#xff1a…

电机驱动开发

最近在搞电机驱动程序&#xff0c;感觉很简单&#xff0c;实际操作却发现里面还有很多猫腻&#xff08;细节&#xff09;。 电机在嵌入式设备中非常常见&#xff0c;例如云台的转动&#xff0c;都是靠电机来驱动的。 电机常见分步进电机、直流电机&#xff0c;相对来说步进电机…

年度大盘点:AIGC、AGI、GhatGPT震撼登场!揭秘人工智能大模型的奥秘与必读书单

这里写目录标题 前言01 《ChatGPT 驱动软件开发》02 《ChatGPT原理与实战》03 《神经网络与深度学习》04 《AIGC重塑教育》05 《通用人工智能》 前言 在2023年&#xff0c;人工智能领域经历了一场前所未有的大爆发&#xff0c;特别是在语言模型领域。新的概念和英文缩写如AIGC、…