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

Kimi LeetCode 3425. 最长特殊路径 Python3实现

以下是 LeetCode 3425. 最长特殊路径 的 Python3 实现。

---

解题思路

这道题的核心是 DFS + 滑动窗口(树上的双指针),时间复杂度 O(n),空间复杂度 O(n)。

关键观察

1. 特殊路径的定义:路径上所有节点的值互不相同。这等价于"无重复元素的最长子数组"问题在树上的扩展。

2. 为什么用滑动窗口? 从根节点出发 DFS,维护当前路径上的节点值集合。当遇到重复值时,需要收缩左边界,直到没有重复值为止。这和数组上的"无重复元素最长子数组"问题本质相同。

3. 具体实现:
- `prefix` 数组:记录从根到当前节点的路径长度前缀和,`prefix[i]` 表示深度为 `i` 的节点到根的路径长度
- `lastSeenDepth`:字典,记录每个节点值最后出现的深度
- `leftBoundary`:当前窗口的左边界深度,确保 `[leftBoundary, currentDepth]` 内无重复值

4. 路径长度计算:`length = prefix[currentDepth] - prefix[leftBoundary]`,节点数 = `currentDepth - leftBoundary`

---

Python3 完整代码

```python
from typing import List

class Solution:
def longestSpecialPath(self, edges: List[List[int]], nums: List[int]) -> List[int]:
n = len(nums)

# 建图:邻接表,存储 (邻居节点, 边权)
graph = [[] for _ in range(n)]
for u, v, w in edges:
graph[u].append((v, w))
graph[v].append((u, w))

# 答案变量
maxLength = 0
minNodes = 1

# prefix[i] = 从根节点到深度为 i 的节点的路径长度
prefix = [0]

# lastSeenDepth[val] = 节点值 val 最后出现的深度
lastSeenDepth = {}

def dfs(u: int, prev: int, leftBoundary: int) -> None:
nonlocal maxLength, minNodes

# 记录当前节点值之前出现的深度
prevDepth = lastSeenDepth.get(nums[u], 0)

# 更新当前节点值的最后出现深度
lastSeenDepth[nums[u]] = len(prefix)

# 收缩左边界:确保 [leftBoundary, currentDepth] 内无重复值
leftBoundary = max(leftBoundary, prevDepth)

# 计算当前路径的长度和节点数
length = prefix[-1] - prefix[leftBoundary]
nodes = len(prefix) - leftBoundary

# 更新答案:优先更长路径,长度相同时更少节点数
if length > maxLength or (length == maxLength and nodes < minNodes):
maxLength = length
minNodes = nodes

# 遍历所有子节点
for v, w in graph[u]:
if v == prev:
continue

# 将子节点加入路径
prefix.append(prefix[-1] + w)
dfs(v, u, leftBoundary)
prefix.pop() # 回溯

# 回溯:恢复当前节点值的最后出现深度
lastSeenDepth[nums[u]] = prevDepth

# DFS 从根节点 0 开始
dfs(0, -1, 0)

return [maxLength, minNodes]
```

---

测试验证

输入 输出 说明
`edges=[[0,1,2],[1,2,3],[1,3,5],[1,4,4],[2,5,6]], nums=[2,1,2,1,3,1]` `[6, 2]` 最长路径 2→5(长度6,2个节点)和 0→1→4(长度6,3个节点),取最少节点数 2
`edges=[[1,0,8]], nums=[2,2]` `[0, 1]` 两节点值相同,只能选单个节点
`edges=[], nums=[5]` `[0, 1]` 单节点
`edges=[[0,1,1],[1,2,1],[2,3,1]], nums=[1,2,3,4]` `[3, 4]` 链状树,无重复值
`edges=[[0,1,1],[0,2,1],[1,3,1],[1,4,1]], nums=[1,2,1,3,4]` `[2, 3]` 有重复值需要收缩窗口

下载完整代码:[leetcode_3425.py](sandbox:///mnt/agents/output/leetcode_3425.py)

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

相关文章:

  • 低查重AI写教材攻略:精选5款AI工具,轻松搞定教材写作难题!
  • GNSS数据处理新手必看:手把手教你读懂RINEX 3.04钟差文件(CLK)里的关键信息
  • django文件对象是什么?
  • Highcharts有版权吗?
  • 对称加密算法的混淆层(S盒)密码学指标详细介绍
  • TVA在具身智能全栈能力体系中的关键作用(6)
  • 限峰功率最大熵定理的理论推导和MATLAB仿真实现(P124302075刘家隆)
  • php里直接塞CSS代码?别傻了,这招让加载快如闪电
  • VMware虚拟机安装Ubuntu Linux:从零搭建开发环境的完整指南
  • TVA:连接数字与物理世界的智能底座(3)
  • 北方高寒矿区专网通信搭建要点,适配低温、粉尘、防爆严苛工况
  • 基于YOLOv8的船舶检测分类系统:从模型训练到部署的完整实践
  • 第十六篇:商业模式重塑——告别数据垄断,拥抱能力订阅
  • YOLOv9的RepNCSPELAN4模块拆解:从代码到结构图,手把手理解这个新‘C3’
  • 新能源车逆市涨价,燃油车持续降价,车市怎么突然分化了?
  • 30N06-ASEMI通用 60V 中低压 Trench MOS管
  • Dify零基础七日实战:从部署到API发布,手把手掌握LLM应用开发
  • 如何用Taskt实现零代码办公自动化:免费RPA工具完整指南
  • 3分钟终极指南:为Windows免费换上macOS专业鼠标指针
  • C++容器——string的基础实现(下)
  • 极低成本 AI 服务:独立开发者的多模型混合路由与流量网关设计
  • STM32学习笔记【25.ADC】
  • 如何快速掌握浏览器资源嗅探:猫抓Cat-Catch扩展的终极完整指南
  • AI渐进编程之五:给 Agent 穿上动力装甲——SIADOS 状态转移方法
  • 二、Prometheus 安装和配置
  • CAN一致性-容错测试--CAN_H与CAN_L短路容错性测试(bus off)
  • 【安卓程序】古诗500首卡片式-墨韵诗笺 · 部署与优化指南
  • 告别云服务器!用旧手机+Debian+AidLux,5分钟搭建你的移动AI开发环境
  • TVA在具身智能产业化体系的落地案例详解(2)
  • metaIPC2 on FreeRTOS: 开发实战指南 (BK7258/BK7259)