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

Kimi LeetCode 3534. 针对图的路径存在性查询 II Rust实现

以下是 LeetCode 3534. 针对图的路径存在性查询 II 的完整 Rust 实现。

---

核心思路

与 Java/Python 版本一致:
1. 排序:按 `nums` 值排序,记录原始下标到排序后位置的映射。
2. 双指针求最远跳:`nxt[i]` 表示从排序后位置 `i` 一步能到达的最远位置。
3. 倍增预处理:`jump[i][k]` 表示从 `i` 连续做 `2^k` 次"最远跳"到达的位置。
4. 查询贪心:同一连通分量内,从高位到低位尝试跳跃,求最少步数。

时间复杂度:`O(n log n + q log n)`,空间复杂度:`O(n log n)`。

---

Rust 代码

```rust
use std::collections::HashMap;

impl Solution {
pub fn path_existence_queries(n: i32, nums: Vec<i32>, max_diff: i32, queries: Vec<Vec<i32>>) -> Vec<i32> {
let n = n as usize;
let max_diff = max_diff as i64;

// 1. 按 nums 值排序,记录原始下标 -> 排序后位置的映射
let mut order: Vec<usize> = (0..n).collect();
order.sort_by_key(|&i| nums[i]);

let mut sorted_nums = vec![0i64; n];
let mut pos = vec![0usize; n];
for (i, &idx) in order.iter().enumerate() {
sorted_nums[i] = nums[idx] as i64;
pos[idx] = i;
}

// 2. 计算连通分量编号(排序后连续段)
let mut comp = vec![0usize; n];
for i in 1..n {
comp[i] = comp[i - 1];
if sorted_nums[i] - sorted_nums[i - 1] > max_diff {
comp[i] += 1;
}
}

// 3. 双指针求 nxt[i]:从排序后位置 i 一步能跳到的最远位置
let mut nxt = vec![0usize; n];
let mut r = 0usize;
for i in 0..n {
while r + 1 < n && sorted_nums[r + 1] - sorted_nums[i] <= max_diff {
r += 1;
}
nxt[i] = r;
}

// 4. 倍增数组:jump[i][k] 表示从 i 连续跳 2^k 次最远跳到达的位置
let log = (n + 1).next_power_of_two().trailing_zeros() as usize;
let mut jump = vec![vec![0usize; log]; n];
for i in 0..n {
jump[i][0] = nxt[i];
}
for k in 1..log {
for i in 0..n {
jump[i][k] = jump[jump[i][k - 1]][k - 1];
}
}

// 5. 回答查询
let mut ans = Vec::with_capacity(queries.len());
for q in &queries {
let u = q[0] as usize;
let v = q[1] as usize;

if u == v {
ans.push(0);
continue;
}

let mut pu = pos[u];
let mut pv = pos[v];
if pu > pv {
std::mem::swap(&mut pu, &mut pv);
}

// 不在同一连通分量,不可达
if comp[pu] != comp[pv] {
ans.push(-1);
continue;
}

// 倍增贪心:从高位到低位,能跳就跳,求最少步数
let mut cur = pu;
let mut steps = 0i32;
for k in (0..log).rev() {
if jump[cur][k] < pv {
steps += (1 << k) as i32;
cur = jump[cur][k];
}
}
// 最后一步一定能到达 pv
ans.push(steps + 1);
}

ans
}
}
```

---

关键点说明

步骤 说明
排序映射 `pos[u]` 将原始节点编号映射到排序后的位置。Rust 中需小心 `usize` 与 `i32` 的类型转换。
连通分量 排序后,若相邻元素差 `> max_diff`,则开启新连通分量。查询时先判断 `comp[pu] == comp[pv]`。
最远跳 `nxt` 双指针在 `O(n)` 内求出每个位置一步能覆盖的最远范围。`nxt[i]` 单调不降。
倍增 `jump` `jump[i][k]` 表示从 `i` 出发连续做 `2^k` 次贪心最远跳到达的位置。利用 `next_power_of_two().trailing_zeros()` 计算所需层数。
查询贪心 从 `pu` 到 `pv`,从高位到低位尝试:如果跳 `2^k` 步后仍到不了 `pv`,就先跳这 `2^k` 步。最终剩余距离只需一步即可覆盖。

> 注意:Rust 中 `nums` 值差可能溢出 `i32`,因此内部计算时转换为 `i64` 处理。

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

相关文章:

  • 直流负载管理中继电器与微控制器的优化方案
  • 2026年7月最新常州积家官方售后联系电话与客户服务中心网点地址 - 积家官方售后服务中心
  • gift-book电子礼簿系统安全解析:完全离线环境下的数据保护方案
  • 2026年青岛空调维修回收出租行业靠谱服务商介绍:空调维修、移机加氟、回收出租服务商选择指南 - 海棠依旧大
  • 深入解析微信小程序反编译技术:使用unveilr探索小程序内部架构
  • 2026年7月最新南通芝柏官方售后联系电话与客户服务中心网点地址 - 亨得利官方服务中心
  • 163MusicLyrics技术深度解析:如何用开源工具破解音乐平台歌词获取难题
  • 3个秘籍免费解锁缠论分析:通达信ChanlunX插件实战指南
  • 钢都闲置黄金处置市场观察|2026 鞍山黄金回收行业乱象与正规渠道筛选科普 - 不晚生活号
  • 如何用免费神器轻松提取游戏文本:3个你不得不知的秘密
  • 2026严选伊犁名表名包奢侈品回收浪琴萧邦朗格爱马仕路易威登LV圣罗兰严选口碑门店排行零隐形费用安心交易 - 谊识预商务
  • 基于TPS61170与PIC32MZ的高效DC-DC升压转换设计
  • 嵌入式电源管理:MAX77654与STM32F334的高效方案
  • 2026年7月最新宝珀广州国际金融中心(IFC)维修保养服务电话 - 宝珀官方售后服务中心
  • 闲置微信立减金如何回收?正规平台流程与可靠性科普 - 圆圆收
  • 上海万国中国官方售后服务体系全解析|全新维修地址及客服电话权威公示(2026年7月最新) - 万国中国服务中心
  • TypeScriptCompiler模板字面量类型:高级类型系统在编译时的处理机制
  • 舞台直拍视频专业处理技术:从色彩校正到音频优化的完整指南
  • 基于深度学习的电路板图像自动检测与缺陷分析工具实践指南
  • 2026年标签打印软件真实测评:有些功能你根本用不上 - 斑马爱打印
  • 2026严选云浮名表名包奢侈品回收帝舵法穆兰沛纳海爱马仕罗意威圣罗兰权威机构排名鉴定严谨报价公道不套路 - 谊识预商务
  • 6款苹方字体完整包:让Windows平台也能享受苹果原生字体体验
  • AMD-Quark量化工具实战:手把手教你将Llama-3.3-70B-Instruct转换为MXFP4格式
  • 高性能 RPC 框架选型指南:gRPC、Thrift 与 brpc 的性能权衡与场景适配
  • 构建跨平台漫画阅读解决方案:Tachidesk-Sorayomi 技术架构与实现指南
  • 2026年7月最新上海天梭官方售后联系电话与客户服务中心网点地址 - 天梭服务中心
  • 电商数据采集|定义、方法、合规性
  • Wonder3D:如何用单张图片快速生成3D模型的完整指南
  • 清奢黄金回收,镇江6家让旧金温柔变现 - 新芸鼎珠宝首饰
  • I2L-MeshNet与其他3D姿态估计方法的对比分析:优势与局限性