当前位置: 首页 > news >正文

Kimi K2.6 思考 LeetCode 3241. 标记所有节点需要的时间 Java实现

LeetCode 3241. 标记所有节点需要的时间 — Java 实现

题目概述

给定一棵无向树,节点编号 `0` 到 `n-1`。每个节点 `i` 被标记的规则:
- 奇数节点:相邻节点在时刻 `x-1` 被标记,则 `i` 在时刻 `x` 被标记(耗时 1)
- 偶数节点:相邻节点在时刻 `x-2` 被标记,则 `i` 在时刻 `x` 被标记(耗时 2)

求以每个节点为起点时,标记所有节点所需的最长时间。

核心思路

将问题转化为树形 DP + 换根(Re-rooting):

1. 边权定义:从节点 `u` 到相邻节点 `v` 的"传播时间"取决于 `v` 的奇偶性
- `v` 为奇数:边权 = 1
- `v` 为偶数:边权 = 2

2. 两次 DFS:
- 第一次 DFS:计算每个节点子树内的最大深度和次大深度
- 第二次 DFS(换根):计算每个节点往父节点方向的最长路径,得到最终答案

Java 实现

```java
class Solution {
private int[] ans;
// node[x][0] = 子树 x 的最大深度 mx1
// node[x][1] = 子树 x 的次大深度 mx2
// node[x][2] = 最大深度要往哪个儿子 my 走
private int[][] node;

public int[] timeTaken(int[][] edges) {
int n = edges.length + 1;
List<Integer>[] g = new ArrayList[n];
Arrays.setAll(g, e -> new ArrayList<>());
for (int[] e : edges) {
int x = e[0], y = e[1];
g[x].add(y);
g[y].add(x);
}
ans = new int[n];
node = new int[n][3];
dfs(0, -1, g);
reroot(0, -1, 0, g);
return ans;
}

// 返回从 x 出发往子树方向的最大深度
private int dfs(int x, int fa, List<Integer>[] g) {
int mx1 = 0, mx2 = 0, my = 0;
for (int y : g[x]) {
if (y == fa) continue;
// 从 x 到 y 的边权: y 是偶数则 2, 奇数则 1
int depth = dfs(y, x, g) + 2 - y % 2;
if (mx1 < depth) {
mx2 = mx1;
mx1 = depth;
my = y;
} else if (mx2 < depth) {
mx2 = depth;
}
}
node[x][0] = mx1;
node[x][1] = mx2;
node[x][2] = my;
return mx1;
}

// from: 从 x 往父节点方向走的最长路径
private void reroot(int x, int fa, int from, List<Integer>[] g) {
ans[x] = Math.max(from, node[x][0]);
for (int y : g[x]) {
if (y != fa) {
// up1: 从 y 往上走到父节点 x 再继续往上
int up1 = from + 2 - x % 2;
// up2: 从 y 往上走到 x, 然后在 x 的其他子树中拐弯
int up2 = (y == node[x][2] ? node[x][1] : node[x][0]) + 2 - x % 2;
reroot(y, x, Math.max(up1, up2), g);
}
}
}
}
```

关键逻辑说明

变量 含义
`node[x][0]` 以 `x` 为根的子树中,往子树方向的最大深度
`node[x][1]` 以 `x` 为根的子树中,往子树方向的次大深度
`node[x][2]` 最大深度对应的子节点编号
`from` 从当前节点往父节点方向走的最长路径长度
`up1` 从子节点 `y` 往上经过 `x` 继续往上的路径
`up2` 从子节点 `y` 往上到 `x`,然后在 `x` 的其他子树中拐弯的路径

复杂度分析

- 时间复杂度:O(n),每个节点访问常数次
- 空间复杂度:O(n),递归栈和存储数组

示例验证

输入:`edges = [[0,1],[0,2]]`

- `i=0`:节点 1(奇数,耗时 1)→ `t=1`,节点 2(偶数,耗时 2)→ `t=2`,答案 = `2`
- `i=1`:节点 0(偶数,耗时 2)→ `t=2`,节点 2 需经过 0(偶数,耗时 2)→ `t=4`,答案 = `4`
- `i=2`:节点 0(偶数,耗时 2)→ `t=2`,节点 1(奇数,耗时 1)→ `t=3`,答案 = `3`

输出:`[2, 4, 3]` ✓

http://www.jsqmd.com/news/1010006/

相关文章:

  • 数据科学家常说的行话:从幽默调侃到技术反思
  • FanControl终极指南:Windows风扇控制软件如何完美解决电脑噪音问题
  • FANG数据科学家面试能力图谱:业务思维、统计严谨与工程落地
  • 告别内存焦虑:实测三星CMM-H混合内存卡,为你的AI服务器低成本扩容
  • Synology硬盘兼容性解锁指南:让群晖NAS支持任意硬盘的终极方案
  • RAG与微调实战决策指南:面向业务的LLM工程化选型
  • 2026年宝鸡本地全屋定制源头厂家行业调研:技术、环保与本地化服务格局分析 - 优质品牌商家
  • Ferret模型原理与多模态指代理解实战
  • 从硬件连接到代码烧录:富芮坤FR801xH蓝牙开发板实战上手全记录
  • 从LSD到M-LSD:盘点那些年我们用过的线段检测算法(附开源代码链接)
  • Kimi K2.6 思考 LeetCode 3241. 标记所有节点需要的时间 Python3实现
  • 白银市2026年最新黄金回收白银回收铂金回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP排行榜 - 盛世金银回收
  • 邯郸市2026年最新黄金回收白银回收铂金回收彩金回收五家靠谱门店TOP排行榜及联系方式地址电话推荐 - 大熊猫898989
  • MathPrompter:结构化提示+分步验证的数学推理工程方法论
  • LLM应用四层纵深防御架构:从提示词注入到输出校验
  • 工业物联网(IIoT)网关实战:将欧姆龙CP系列PLC数据接入MQTT/云平台(基于Node-RED或IoT边缘设备)
  • 终极解密:3步解锁你的加密音频宝藏,让音乐自由流动
  • 告别破解版!手把手教你用WinLicense 3.1.3.0为你的软件穿上‘防弹衣’
  • 从Sovit2D/3D组态软件实战出发,聊聊SCADA系统在智慧水务项目里是怎么用的
  • 百色市2026年最新黄金回收白银回收铂金回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP排行榜 - 盛世金银回收
  • 告别Google Play自动签名:手把手教你用jarsigner和KeyStore重签Android AAB包
  • 不止于替代:深度评测GD60914 vs MLX90614,在600℃高温、防尘与远距离探测上的实际表现
  • 3D建模终极痛点:如何在不丢失形变键的情况下应用Blender细分表面修改器?
  • 蚌埠市2026年最新黄金回收白银回收铂金回收彩金回收五家靠谱门店及联系方式地址电话推荐TOP排行榜 - 盛世金银回收
  • LSLib完全指南:5步快速掌握《神界原罪》与《博德之门3》MOD制作
  • LLM Agent工程实践:从工具调用到生产级容错的完整落地指南
  • 终极指南:5分钟在Windows电脑上安装安卓应用的完整教程
  • MLflow本地实验追踪实战:30分钟构建可追溯可复现的机器学习工作流
  • 微信单向好友检测终极指南:5分钟找出谁删除了你
  • 提示工程已死,指令架构永生:深度复盘 GPT-5.5 与 Claude 4.7 带来的范式转移