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

Kimi LeetCode 3464. 正方形上的点之间的最大距离 Rust实现

以下是 LeetCode 3464 的 Rust 实现,核心思路是二分答案 + 单调队列优化 DP。

解题思路

1. 二分答案:答案范围是 [0, \text{side}],对最小曼哈顿距离进行二分搜索
2. 展开正方形:将正方形边界按顺时针展开为一维序列,按边分类排序
3. 可行性检验:对于候选距离 d,用单调队列优化的 DP 判断能否选出 k 个点,使得相邻点间曼哈顿距离 \ge d

完整代码

```rust
use std::collections::VecDeque;

impl Solution {
pub fn max_distance(side: i32, points: Vec<Vec<i32>>, k: i32) -> i32 {
let ordered = Self::get_ordered_points(side, &points);
let mut l = 0;
let mut r = side;

while l < r {
let m = (l + r + 1) / 2;
if Self::is_valid_distance(&ordered, k, m) {
l = m;
} else {
r = m - 1;
}
}
l
}

// 判断能否选出 k 个点,使得相邻点间曼哈顿距离 >= d
fn is_valid_distance(ordered: &[(i32, i32)], k: i32, d: i32) -> bool {
let mut dq: VecDeque<Sequence> = VecDeque::new();
dq.push_back(Sequence::new(ordered[0].0, ordered[0].1,
ordered[0].0, ordered[0].1, 1));
let mut max_length = 1;

for i in 1..ordered.len() {
let (x, y) = ordered[i];
let mut start_x = x;
let mut start_y = y;
let mut length = 1;

// 维护单调队列:保留能作为起点的序列
while let Some(first) = dq.front() {
if Self::manhattan(x, y, first.end_x, first.end_y) >= d {
if Self::manhattan(x, y, first.start_x, first.start_y) >= d
&& first.length + 1 >= length {
start_x = first.start_x;
start_y = first.start_y;
length = first.length + 1;
max_length = max_length.max(length);
}
dq.pop_front();
} else {
break;
}
}
dq.push_back(Sequence::new(start_x, start_y, x, y, length));
}

max_length >= k
}

// 曼哈顿距离
fn manhattan(x1: i32, y1: i32, x2: i32, y2: i32) -> i32 {
(x1 - x2).abs() + (y1 - y2).abs()
}

// 将正方形边界上的点按顺时针顺序展开
fn get_ordered_points(side: i32, points: &[Vec<i32>]) -> Vec<(i32, i32)> {
let mut left: Vec<(i32, i32)> = Vec::new();
let mut top: Vec<(i32, i32)> = Vec::new();
let mut right: Vec<(i32, i32)> = Vec::new();
let mut bottom: Vec<(i32, i32)> = Vec::new();

for point in points {
let x = point[0];
let y = point[1];
if x == 0 && y > 0 {
left.push((x, y));
} else if x > 0 && y == side {
top.push((x, y));
} else if x == side && y < side {
right.push((x, y));
} else {
bottom.push((x, y));
}
}

// 按顺时针方向排序各边上的点
left.sort_by_key(|p| p.1); // 左:y 从小到大
top.sort_by_key(|p| p.0); // 上:x 从小到大
right.sort_by(|a, b| b.1.cmp(&a.1)); // 右:y 从大到小
bottom.sort_by(|a, b| b.0.cmp(&a.0)); // 下:x 从大到小

let mut ordered = Vec::new();
ordered.extend(left);
ordered.extend(top);
ordered.extend(right);
ordered.extend(bottom);
ordered
}
}

// 记录序列信息
struct Sequence {
start_x: i32, start_y: i32, // 序列起点
end_x: i32, end_y: i32, // 序列终点
length: i32, // 序列长度(包含的点数)
}

impl Sequence {
fn new(start_x: i32, start_y: i32, end_x: i32, end_y: i32, length: i32) -> Self {
Self { start_x, start_y, end_x, end_y, length }
}
}
```

关键点说明

要点 说明
二分答案 经典"最大化最小值"问题,答案范围 [0, \text{side}],k \ge 4 时答案不超过 \text{side}
展开正方形 按顺时针将边界点排成一维序列:左(y↑)、上(x↑)、右(y↓)、下(x↓)
单调队列优化 DP 状态 `dp[i]` 表示以第 i 个点结尾的最长合法序列长度。利用单调性,队首维护最优起点
可行性检验 对于候选距离 d,检查是否存在长度 \ge k 的合法序列

复杂度分析

- 时间复杂度:O(n \log \text{side}),其中 n = \text{points.len()}。二分搜索 O(\log \text{side}),每次检验 O(n)
- 空间复杂度:O(n)

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

相关文章:

  • 无需复杂设置!这款会议APP一键录音不漏关键内容
  • HarmonyOS ArkTS 实战:实现一个校园食堂排队取餐记录应用
  • VLC Android电视版专业配置手册:解锁大屏媒体中心的终极潜力
  • RAG的“语义相似≠真正相关”陷阱:从向量检索到图RAG的架构演进
  • Java面向对象课程设计:学生成绩管理系统
  • Python的struct,把C语言那套二进制魔法,一把塞进你的字符串
  • 收藏!2026年企业决胜关键:AI智能体(小白程序员必看)
  • 华为HarmonyOS设备上如何轻松配置microG服务框架:完整指南
  • Java事务与MySQL事务的关系及MVCC通俗解析
  • OpenBMC:服务器的带外管理
  • MC6470与dsPIC33EP运动控制方案在工业自动化中的应用
  • Claude Code那些高级功(一)
  • 30分钟掌握Codex:AI代码生成从入门到实战
  • # 双曲RAG框架:从表示空间几何特性重构检索增强生成流程
  • MAX9744与PIC18F45K40构建高效数字音频系统
  • 大模型微调 : LLaMA-Factory + Qwen3:4b
  • 个人分享|小区物业管理系统源码与配套论文,课设毕设参考素材!
  • TotalSegmentator:一站式医学图像分割的终极解决方案
  • Labelme 5.3.1 批量标注与转换:100张图片自动生成VOC/COCO格式数据集
  • 第21讲:自定义类型:联合和枚举
  • 六西格玛在AI与云原生时代的实战重构:女性技术专家的质量方法论
  • 程序员求职全链路防坑手册——培训贷、虚假高薪、外包套路、阴阳合同一次性拆解
  • 【Software Engineering】Iterative Development, make it Work, then Better
  • LeRobot + LIBERO 机器人仿真评估全流程:模型下载、环境搭建与踩坑指南
  • Mi-Create终极教程:免费打造小米手表专属表盘的完整指南
  • 系统安全核心要素——构建“铜墙铁壁“的系统
  • Zed 新特性:Git面板视图重构,像VS Code看齐了。
  • 编译原理:高级程序语言的定义
  • PyTorch 2.0 自动求导实战:3步构建动态计算图与梯度检查
  • 二极管、三极管、mos管