news 2026/8/16 23:35:32

千问 LeetCode 3915. 距离至少为 K 的交替子序列的最大和 Rust实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
千问 LeetCode 3915. 距离至少为 K 的交替子序列的最大和 Rust实现

这道题是 LeetCode 3915「距离至少为 K 的交替子序列的最大和」,核心思路是 DP + 值域离散化 + 树状数组(Fenwick Tree)优化,将复杂度从 O(n²) 降到 O(n log n)。

题目理解

给定数组 nums 和整数 k,选一个下标严格递增的子序列,满足:
1. 相邻选中下标之差 ≥ k
2. 选出的值严格交替(小大 或 大小 波动,不能相等)
3. 求最大和

核心思路

1. DP 状态:up[i] 表示以 nums[i] 结尾、最后一步是"递增"(前一个值 < 当前值)的最大和;down[i] 表示以 nums[i] 结尾、最后一步是"递减"的最大和
2. 转移逻辑:
- up[i] = nums[i] + max{down[j]},其中 j ≤ i-k 且 nums[j] < nums[i]
- down[i] = nums[i] + max{up[j]},其中 j ≤ i-k 且 nums[j] > nums[i]
3. 延迟激活:只有当 i ≥ k 时,才把 i-k 位置的状态加入树状数组,保证下标距离 ≥ k
4. 树状数组优化:用两棵树状数组分别维护"值小于当前值"和"值大于当前值"的最大 DP 值,查询/更新均为 O(log n)

Rust 实现

use std::cmp::max;
use std::collections::BTreeSet;

struct FenwickTree {
n: usize,
tree: Vec<i64>,
}

impl FenwickTree {
fn new(n: usize) -> Self {
FenwickTree {
n,
tree: vec![i64::MIN / 2; n + 2], // 初始化为极小值
}
}

// 单点取 max 更新
fn update(&mut self, mut idx: usize, val: i64) {
while idx <= self.n {
self.tree[idx] = max(self.tree[idx], val);
idx += idx & idx.wrapping_neg(); // idx += idx & (-idx)
}
}

// 前缀最大值查询 [1, idx]
fn query(&self, mut idx: usize) -> i64 {
let mut res = i64::MIN / 2;
while idx > 0 {
res = max(res, self.tree[idx]);
idx -= idx & idx.wrapping_neg();
}
res
}
}

impl Solution {
pub fn max_alternating_sum(nums: Vec<i32>, k: i32) -> i64 {
let n = nums.len();
let k = k as usize;

// 1. 值域离散化
let mut sorted: Vec<i32> = nums.clone();
sorted.sort();
sorted.dedup();
let m = sorted.len();

// 2. 两棵树状数组
// bit_down:维护 down 值,用于查询"值小于当前值"的最大 down
// bit_up_rev:维护 up 值(倒序坐标),用于查询"值大于当前值"的最大 up
let mut bit_down = FenwickTree::new(m);
let mut bit_up_rev = FenwickTree::new(m);

let mut up = vec![0i64; n];
let mut down = vec![0i64; n];
let mut ans = 0i64;

for i in 0..n {
// 3. 延迟激活:把 i-k 位置的状态加入树状数组
if i >= k {
let prev = i - k;
let prev_rank = sorted.binary_search(&nums[prev]).unwrap() + 1; // 1-based
bit_down.update(prev_rank, down[prev]);
bit_up_rev.update(m - prev_rank + 1, up[prev]); // 倒序映射,后缀变前缀
}

let cur_rank = sorted.binary_search(&nums[i]).unwrap() + 1; // 1-based

// 4. 状态转移
// up[i]:前一个值 < nums[i],从 bit_down 查询值域 [1, cur_rank-1] 的最大 down
let best_down = bit_down.query(cur_rank - 1);
up[i] = nums[i] as i64 + if best_down <= i64::MIN / 2 { 0 } else { best_down };

// down[i]:前一个值 > nums[i],从 bit_up_rev 查询值域 [cur_rank+1, m] 的最大 up
let best_up = bit_up_rev.query(m - cur_rank);
down[i] = nums[i] as i64 + if best_up <= i64::MIN / 2 { 0 } else { best_up };

ans = max(ans, max(up[i], down[i]));
}

ans
}
}

关键点解析

- 值域离散化:nums[i] 最大 10⁵,但实际不同值最多 n 个,离散化后压缩到 [1, m],树状数组大小可控
- 延迟激活:这是处理"下标距离 ≥ k"的关键技巧——遍历时不立即把当前状态加入树状数组,而是等 k 步后再加入,这样查询时自然只看到距离 ≥ k 的前驱状态
- 后缀查询技巧:树状数组天然支持前缀查询,要查"值大于当前值"的最大值,把排名 r 反转为 m - r + 1,就把后缀查询变成了前缀查询
- Rust 特有注意点:idx & (-idx) 在 Rust 中需要用 idx & idx.wrapping_neg() 来避免无符号整数的取负溢出问题;树状数组初始值设为 i64::MIN / 2 防止加法溢出
- 时间复杂度:O(n log n),空间 O(n)

示例验证

- nums = [5,4,2], k = 2:选下标 [0,2],值 [5,2],距离 2-0=2≥k,5>2 严格交替,得分 7 ✅
- nums = [3,5,4,2,4], k = 1:选下标 [0,1,3,4],值 [3,5,2,4],3<5>2<4 严格交替,得分 14 ✅
- nums = [5], k = 1:长度为 1 始终有效,得分 5 ✅

需要我把树状数组优化 DP 的通用模板整理出来吗?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/16 23:35:21

动态内存分配(Dynamic Memory Allocation)是C语言中在程序运行时(而非编译时)向操作系统申请和释放内存空间的机制

动态内存分配&#xff08;Dynamic Memory Allocation&#xff09;是C语言中在程序运行时&#xff08;而非编译时&#xff09;向操作系统申请和释放内存空间的机制&#xff0c;主要用于处理大小未知、生命周期不确定或需灵活管理的数据结构&#xff08;如链表、树、动态数组等&a…

作者头像 李华
网站建设 2026/8/16 23:35:16

Windows 11升级检测全攻略:官方工具使用与硬件要求深度解析

1. 项目概述&#xff1a;为什么我们需要找到Win11检测工具&#xff1f;如果你是Windows用户&#xff0c;最近可能被“Windows 11”这个词刷屏了。新系统带来了全新的界面设计、性能优化和一系列诱人的功能&#xff0c;比如安卓应用支持、更现代化的窗口管理。但问题来了&#x…

作者头像 李华
网站建设 2026/8/16 23:29:18

ffmpeg 初始化配置及基本概念与套路

目录 链接库文件查看 HEVC 错误之一 Codec type or id mismatches 测试文件信息 解决方法 HEVC 错误之二 Failed to set config: -6 测试文件信息 调试开关 解决方法 帧的分类 软件帧&#xff08;System Memory Frame&#xff09; DRM PRIME 帧&#xff08;DMA-Buf …

作者头像 李华
网站建设 2026/8/16 23:28:11

KKCE: 基于网站测速的HTTP/2优先级,全球300+节点-快快测

一、引言&#xff1a;为什么 HTTP/2 开了&#xff0c;首屏反而更慢&#xff1f; 在协议升级时&#xff0c;我们常有一个预期&#xff1a;只要服务端支持 HTTP/2&#xff0c;前端性能就会自动提升。多路复用、头部压缩、请求优先级——这些特性听起来都很美好。 然而&#xff…

作者头像 李华
网站建设 2026/8/16 23:27:29

【毕设作品】基于FastAPI的智能教室人脸考勤与注意力分析系统的设计与实现

文章目录前言题目技术栈功能概述实现页面截图系统测试系统测试目的系统功能测试系统测试结论文章参考我的优势代码参考数据库参考源码获取前言 ❤️博主简介&#xff1a;全网累计学员1000&#xff0c;培训机构讲师、全栈开发工程师、知乎/小红书优秀作者、腾讯云/阿里云VIP客户…

作者头像 李华
网站建设 2026/8/16 23:19:50

YOLOv8 火焰烟雾检测全栈工程|2 类别 VOC/YOLO 消防数据集、PyQt5 可视化 GUI、ONNX 轻量化推理、全套训练评估曲线落地

目录 一、前言 二、13647 张火焰烟雾 2 类别数据集完整解析 2.1 数据集基础完整参数 2.2 消防火焰烟雾数据集专属优势 2.3 数据集固有短板与配套涨点方案 三、YOLOv8 消防火情专属涨点核心原理 四、三大智慧消防落地应用案例 案例 1 工业园区全域监控火情预警 业务痛点…

作者头像 李华