力扣:二叉树着色游戏(DFS详解)
有两位极客玩家参与了一场「二叉树着色」的游戏。游戏中,给出二叉树的根节点 root,树上总共有 n 个节点,且 n 为奇数,其中每个节点上的值从 1 到 n 各不相同。
游戏从「一号」玩家开始(「一号」玩家为红色,「二号」玩家为蓝色),最开始时,
「一号」玩家从 [1, n] 中取一个值 x(1 <= x <= n);
「二号」玩家也从 [1, n] 中取一个值 y(1 <= y <= n)且 y != x。
「一号」玩家给值为 x 的节点染上红色,而「二号」玩家给值为 y 的节点染上蓝色。
之后两位玩家轮流进行操作,每一回合,玩家选择一个他之前涂好颜色的节点,将所选节点一个 未着色 的邻节点(即左右子节点、或父节点)进行染色。
如果当前玩家无法找到这样的节点来染色时,他的回合就会被跳过。
若两个玩家都没有可以染色的节点时,游戏结束。着色节点最多的那位玩家获得胜利 ✌️。
现在,假设你是「二号」玩家,根据所给出的输入,假如存在一个 y 值可以确保你赢得这场游戏,则返回 true;若无法获胜,就请返回 false。
获胜的关键是要取得更多的节点数量。假设玩家1取了x节点,则我们可以认为玩家2可以取不包含x及其子树的节点、x的左节点和x的右节点。
1、令x的左节点数量为left,右节点数量为right。half为一半节点数量
left>half 或 right>half; // 必赢
left == half 或 right == half; // 必输
half<=left+right<2*half; // 玩家1的节点数加上父节点及其本身已经超过half,必输
left+right<half; // 只要选择x节点的父节点即可
int left = 0;
int right = 0;
int m;
public boolean btreeGameWinningMove(TreeNode root, int n, int x) {
m = x;
int half = n/2;
dfs(root);
// 此时的left和right应经更新
if ( left > half || right > half || (left+right) < half) {
return true;
} else {
return false;
}
}
public int dfs(TreeNode node) {
int leftNum = 0;
int rightNum = 0;
if (node.left != null) {
leftNum = dfs(node.left);
}
if (node.right != null) {
rightNum = dfs(node.right);
}
if (node.val == m) {
left = leftNum;
right = rightNum;
}
return leftNum+rightNum+1;
}
这里我们主要看一下dfs的具体应用。
可以看出dfs方法中给出了搜索的具体操作:在给定node情况下,对node节点的左右节点分别搜索,记录个数。记住这里面用到了递归的思想,在进行一系列左节点搜索结束后倒叙返回搜索上一节点的右节点。(要想清楚递归的真正迭代操作)首先从0-->n递归,递归结束后向上返回到第n-1递归进行判断,以此类推至第0次。当其中某个节点值为m,则返回m节点处的左右节点个数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现