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

DeepSeek LeetCode 3605. 数组的最小稳定性因子 Rust实现

这个问题的核心是二分答案 + 贪心验证,其中预处理所有长度为 mid+1 的稳定子数组是关键。

这里提供一个结合了线段树进行区间 GCD 查询和贪心区间覆盖的 Rust 实现,思路清晰且易于理解。

```rust
use std::cmp::max;

impl Solution {
pub fn min_stable(nums: Vec<i32>, max_c: i32) -> i32 {
let n = nums.len();
if n == 0 {
return 0;
}

// 构建线段树用于快速查询任意区间的 GCD
let mut size = 1;
while size < n {
size <<= 1;
}
let mut seg = vec![0; size * 2];
for i in 0..n {
seg[size + i] = nums[i];
}
for i in (1..size).rev() {
seg[i] = Self::gcd(seg[i * 2], seg[i * 2 + 1]);
}

// 闭包:查询区间 [l, r] 的 GCD
let range_gcd = |l: usize, r: usize| -> i32 {
let mut l = l + size;
let mut r = r + size;
let mut res_left = 0;
let mut res_right = 0;
while l <= r {
if l % 2 == 1 {
res_left = Self::gcd(res_left, seg[l]);
l += 1;
}
if r % 2 == 0 {
res_right = Self::gcd(seg[r], res_right);
r -= 1;
}
l >>= 1;
r >>= 1;
}
Self::gcd(res_left, res_right)
};

// 验证函数:检查稳定性因子是否 <= limit
let feasible = |limit: usize| -> bool {
let mut used = 0;
let mut last_chosen = -1; // 上一个修改点的位置

// 只需检查所有长度为 limit + 1 的窗口
for start in 0..(n - limit) {
let end = start + limit;
// 如果窗口 GCD >= 2,则这是一个必须被“破坏”的稳定子数组
if range_gcd(start, end) >= 2 {
// 如果上一个修改点不在当前窗口内,则必须在此窗口内进行一次修改
if last_chosen < start as isize {
used += 1;
last_chosen = end as isize; // 贪心地选择窗口右端点
if used > max_c {
return false;
}
}
}
}
true
};

// 二分查找最小可行的稳定性因子
let mut left = 0;
let mut right = n;
while left < right {
let mid = (left + right) / 2;
if feasible(mid) {
right = mid;
} else {
left = mid + 1;
}
}
left as i32
}

// 辅助 gcd 函数
fn gcd(a: i32, b: i32) -> i32 {
if b == 0 { a } else { Self::gcd(b, a % b) }
}
}
```

核心思路说明

1. 问题转化:判断能否通过最多 maxC 次修改,使数组的“稳定性因子”不超过 L。这等价于判断所有长度为 L+1 的稳定子数组(GCD >= 2)能否被最多 maxC 个点“击中”。
2. 贪心验证 (Greedy Check):对于给定的 L,从左到右扫描所有长度为 L+1 的窗口。如果遇到一个稳定窗口,就在其右端点处进行修改(相当于放置一个“断点”)。这是处理区间覆盖问题的最优贪心策略:要覆盖一个区间,点在右端点能最大化覆盖后续区间的可能性。统计所需的修改次数,若不超过 maxC,则 L 可行。
3. 区间 GCD 查询:为了快速判断一个窗口是否稳定,需要使用高效的数据结构。这里选择线段树,可以在 O(log n) 时间内查询任意区间的 GCD,预处理复杂度 O(n)。另一种更优的预处理方法是 LogTrick,可以在 O(n log U) 时间内算出所有位置的关键信息,并用于 O(n) 的验证。
4. 二分答案:可行性关于 L 是单调的(L 越大越容易实现),因此可以对答案 [0, n] 进行二分,找到最小的可行 L。

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

相关文章:

  • 金融级数据库的 AI 风控引擎:实时交易反欺诈的 300ms 生死线
  • EllipticCurveKeyPair核心功能详解:签名验证与加解密的实现原理
  • 大模型AI搜索信源排名规则深度解析:豆包 vs DeepSeek 引用逻辑对比与GEO实战策略
  • Aperture性能优化指南:提升系统吞吐量的8个实用方法
  • ID-based RAG FastAPI多模型支持:OpenAI、Azure、Hugging Face等7种嵌入模型配置指南
  • Cursor连接数据库突然失败?揭秘Connection Timeout背后的4层协议栈真相(含Wireshark抓包验证)
  • BlockLauncher:Android版Minecraft终极启动器与Mod平台完全指南
  • KnpGaufretteBundle源码解析:深入理解文件系统抽象层实现原理
  • Aperture多语言SDK使用教程:Go、Java、Python、JavaScript全攻略
  • AI办公提效专栏目录
  • HarmonyOS ArkTS 内存泄漏排查实战:从生命周期订阅到释放策略、缓存上限和回归记录
  • 解决asdf-ruby常见问题:Ruby版本不显示?构建失败?这里有答案
  • React-PDF终极指南:如何生成专业级高清PDF文档
  • Ollama多模型管理效能跃迁:实测单节点并发托管17个LoRA微调模型的资源编排方案(含Prometheus监控看板)
  • Containerum仪表板定制化:创建个性化监控视图与数据可视化
  • C语言字符型数据类型详解:从ASCII到实际应用
  • 【企业级AI Banner生产体系】:已服务86家品牌,实测CTR提升2.8倍,这套SOP现在限时公开
  • 2026年成都资格川菜馆子 怕踩雷 适配多场景排行推荐 - 资讯纵览
  • 2026毓典奢品汇|7月19日天津欧米茄回收行情 海马碟飞超霸全系变现攻略 腕表避坑指南 - 二奢行情速报
  • 告别版本混乱!asdf-ruby插件安装与配置的完整步骤
  • CF1079div2
  • Kafka-Storm-Starter代码解析:核心类库的实现细节
  • 【限时解密】头部MCN私有数字人直播中台架构图:含ASR延迟<200ms的FPGA加速方案与商用授权清单
  • QCNet核心架构解析:查询中心化轨迹预测的10个关键技术要点
  • HTTPotion最佳实践:企业级HTTP客户端配置指南
  • H3C交换机SNMP网管识别配置实例
  • SplinterDB与传统存储对比:为什么它是NVMe设备的理想选择?[特殊字符]
  • VSCode git/gerrit解冲突
  • KnpGaufretteBundle多适配器配置实战:本地、FTP、SFTP、云存储统一管理
  • 终极指南:Awesome Pydantic中的FastAPI与现代框架集成实践