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

Kimi LeetCode 3544. 子树反转和 Rust实现

这是 LeetCode 3544. 子树反转和 的 Rust 实现。

思路

本题是树形 DP + 记忆化搜索。

核心观察: 反转一个节点会影响其整个子树。约束条件要求:若两个反转节点存在祖先关系,则它们之间的距离(边数)必须至少为 `k`。

状态定义: `dp(u, steps, inverted)` 表示:
- 以节点 `u` 为根的子树
- `steps`:距离最近一个祖先反转节点已经经过了多少条边(上限为 `k`)
- `inverted`:当前节点是否被反转(即当前子树整体是否被乘了 `-1`)

转移:
- 若 `steps == k`:当前节点可以再次反转,取 `max(不反转, 反转)`
- 若 `steps < k`:当前节点不能反转,只能继承当前状态
- 对于子节点 `v`:
- 不反转 `u`:子节点继承 `min(steps + 1, k)`,反转状态不变
- 反转 `u`(若允许):子节点的 `steps` 重置为 `1`,反转状态翻转

初始状态: 根节点 `0` 的 `steps = k`,表示根节点可以立即反转。

复杂度: `O(n · k)` 状态数,每个状态遍历所有子节点,总复杂度 `O(n · k)`。

---

```rust
impl Solution {
pub fn subtree_inversion_sum(edges: Vec<Vec<i32>>, nums: Vec<i32>, k: i32) -> i64 {
let n = edges.len() + 1;
let k = k as usize;

// 构建邻接表
let mut graph = vec![vec![]; n];
for edge in edges {
let u = edge[0] as usize;
let v = edge[1] as usize;
graph[u].push(v);
graph[v].push(u);
}

// memo[u][steps][inverted],None 表示未计算
let mut memo = vec![vec![vec![None; 2]; k + 1]; n];
// parent[i] = n 表示无父节点(根节点)
let mut parent = vec![n; n];

fn dfs(
u: usize,
steps: usize,
inverted: usize,
graph: &Vec<Vec<usize>>,
nums: &Vec<i32>,
k: usize,
parent: &mut Vec<usize>,
memo: &mut Vec<Vec<Vec<Option<i64>>>>,
) -> i64 {
if let Some(val) = memo[u][steps][inverted] {
return val;
}

let inv = inverted == 1;
// 当前节点在 inherited 状态下的值
let num = if inv { -(nums[u] as i64) } else { nums[u] as i64 };
// 如果当前节点再反转一次(符号翻转)
let mut neg_num = -num;
let mut sum = num;

for &v in &graph[u] {
if v == parent[u] {
continue;
}
parent[v] = u;

// 不反转当前节点:子节点继承 steps+1(上限 k),反转状态不变
sum += dfs(v, (steps + 1).min(k), inverted, graph, nums, k, parent, memo);

// 如果距离足够远(steps == k),可以尝试反转当前节点
if steps == k {
neg_num += dfs(v, 1, 1 - inverted, graph, nums, k, parent, memo);
}
}

// 如果当前可以反转,取最大值;否则只能不反转
let res = if steps == k { sum.max(neg_num) } else { sum };
memo[u][steps][inverted] = Some(res);
res
}

dfs(0, k, 0, &graph, &nums, k, &mut parent, &mut memo)
}
}
```

---

验证:
- 示例 1:`edges=[[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], nums=[4,-8,-6,3,7,-2,5], k=2` → 27 ✓
- 示例 2:`edges=[[0,1],[1,2],[2,3],[3,4]], nums=[-1,3,-2,4,-5], k=2` → 9 ✓
- 示例 3:`edges=[[0,1],[0,2]], nums=[0,-1,-2], k=3` → 3 ✓

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

相关文章:

  • 2026年7月最新常州劳力士官方售后服务热线与网点地址查询 - 劳力士官方服务中心
  • PID控制算法C语言实现:位置式与增量式3种代码结构对比与性能分析
  • 蓝牙5.4高保真音频系统设计与实现
  • Iwe iwe-v0.1.9 官方版下载(夸克网盘+百度网盘,SHA256校验)
  • VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异
  • ChatGPT SWOT分析法失效的5个信号(附诊断流程图),90%团队在第3步就误判了竞争优势
  • Unity WebGL AR项目一键部署实战:从构建到生成可分享测试链接
  • 【VCD】A Fast Partial Video Copy Detection Using KNN and Global Feature Database
  • ChatGPT卡顿不是网络问题!资深MLOps工程师拆解:模型加载延迟、KV缓存碎片、上下文长度溢出三大“静默杀手”
  • 课表管理系统-springboot + vue
  • 技术筑基 AI 赋能,四川映旭传媒打造动画短剧承制降本增效新标杆
  • WarcraftHelper插件:魔兽争霸3终极性能优化完全指南
  • VBA 与 Python openpyxl 批量转换 TXT:5 个文件场景下的效率与灵活性评测
  • 智慧树刷课插件:5分钟实现自动化学习的智能助手
  • Burp Suite 2026.6 汉化与激活:3种主流系统(Win/Linux/Mac)一键启动脚本配置
  • 毕设 深度学习车道线检测(源码+论文)
  • 3款主流CAN分析仪软件对比:CANTest vs ZCANPro vs USB-CAN Tool 功能实测
  • 如何高效进行多图像AI处理:IPAdapter Plus同步生成完整指南
  • HTML5 Audio API实战:为原创手书项目集成背景音乐控制
  • 腾讯音乐开源ChatBI + Headless BI平台SuperSonic全面使用指南
  • Unity序列帧动画输出全攻略:Recorder+Timeline实战与透明通道处理
  • OpenCV 4.5.5 + Contrib 编译优化:VSCode + CMake 配置 3 步集成开发环境
  • IEEE 754 浮点数编码深度解析:从 DataLab 的 float_twice 到舍入与溢出
  • UE5 C++增强输入绑定:三大核心细节与完整避坑指南
  • 【RT-DETR涨点改进】26 跨平台SDK封装:从Python原型到C++生产级部署
  • PX4 模块化架构解析:uORB 消息总线如何连接 10+ 个核心进程
  • 三步轻松下载国家中小学智慧教育平台电子课本:新手完全指南
  • 亨得利官方名表服务中心|最新热线和详细维修地址权威信息公告(2026年7月更新) - 亨得利官方博客
  • Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案
  • 校园在线拍卖系统-springboot + vue