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

Kimi LeetCode 3883. 统计满足数位和数组的非递减数组数目 Rust实现

这是 LeetCode 3883 的 Rust 实现,基于动态规划 + 双指针优化的思路。

解题思路

1. 预处理:枚举 `0..=5000` 所有数字,按数位和分组。最大数位和为 `4+9+9+9=31`(数字4999),所以最多32个组。

2. 动态规划:`f[x]` 表示以数字 `x` 结尾的有效非递减数组数量。设虚拟起点 `f[0] = 1`(前一个数位和为0,数字为0)。

3. 双指针转移:对于当前数位和 `cur`,遍历该组所有数字 `x`。用双指针在上一组(数位和 `pre`)中累加所有 `<= x` 的 `f` 值,即为以 `x` 结尾的方案数。

4. 取模:结果对 `10^9 + 7` 取模。

```rust
use std::sync::OnceLock;

const MOD: i64 = 1_000_000_007;
const MX: usize = 5001;
const MAX_DIGIT_SUM: usize = 31; // 4999 的数位和最大为 31

/// 预计算:按数位和分组数字 0..5000
fn get_sum_to_nums() -> &'static Vec<Vec<usize>> {
static SUM_TO_NUMS: OnceLock<Vec<Vec<usize>>> = OnceLock::new();
SUM_TO_NUMS.get_or_init(|| {
let mut sum_to_nums: Vec<Vec<usize>> = vec![Vec::new(); MAX_DIGIT_SUM + 1];
let mut dig_sum = vec![0usize; MX];
for x in 0..MX {
if x > 0 {
dig_sum[x] = dig_sum[x / 10] + (x % 10);
}
sum_to_nums[dig_sum[x]].push(x);
}
sum_to_nums
})
}

struct Solution;

impl Solution {
pub fn count_arrays(digit_sum: Vec<i32>) -> i32 {
let sum_to_nums = get_sum_to_nums();
let mut f: Vec<i64> = vec![0; MX];
f[0] = 1; // 以 0 结尾的方案数为 1(虚起点)
let mut pre: usize = 0; // 上一个数位和,初始为 0

for &cur in &digit_sum {
let cur = cur as usize;
if cur > MAX_DIGIT_SUM {
return 0;
}

let a = &sum_to_nums[pre]; // 前一个数位和对应的数字列表
let b = &sum_to_nums[cur]; // 当前数位和对应的数字列表

let mut j: usize = 0;
let m = a.len();
let mut sum: i64 = 0;

for &x in b {
// 累加所有满足 a[j] <= x 的 f[a[j]]
while j < m && a[j] <= x {
sum += f[a[j]];
j += 1;
}
f[x] = sum % MOD;
}

pre = cur; // 更新前一个数位和
}

let mut ans: i64 = 0;
for &x in &sum_to_nums[pre] {
ans += f[x];
}
(ans % MOD) as i32
}
}

fn main() {
// 示例测试
let tests = vec![
(vec![25, 1], 6),
(vec![1], 4),
(vec![2, 49, 23], 0),
];

for (digit_sum, expected) in tests {
let result = Solution::count_arrays(digit_sum.clone());
println!("digitSum = {:?}, result = {}, expected = {}", digit_sum, result, expected);
assert_eq!(result, expected);
}
}
```

复杂度分析

- 时间复杂度:预处理 `O(5000)`;DP 阶段每步双指针总扫描量不超过两组长度之和,总体 `O(n × L_max)`,其中 `L_max` 是单组最大长度(实际很小)。
- 空间复杂度:`O(5000)`,用于 `f` 数组和预计算的分组。

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

相关文章:

  • Python实战 | 只需“4步”入门网络爬虫(有福利哦)
  • PulseView终极指南:快速掌握开源逻辑分析仪图形化工具
  • 2026年:镇江专利资源收购转让平台规避专利交易隐患,安心完成知识产权流转-慕凡企业管理 - 行业甄选汇
  • AI Agent在企业级客服场景中的幻觉治理工程实践
  • 多商户家政接单小程序系统开发方案
  • 深入解析空间换时间与时间换空间:算法设计与系统优化的核心权衡
  • 北京市中伦文德(福州)律师事务所 梁睿律师专攻取保候审 - 专业优选推荐榜
  • Transformer与离线强化学习在广告自动出价中的实践:GAVE框架解析
  • 学生课程汇报PPT,哪个AI工具最好用?我实测了6款,结论有点意外
  • 深圳废旧金属回收,2026年环保变现新思路 - 品牌优选官
  • C++Builder OLE自动化Excel:从基础封装到大数据报表实战
  • 2026年国内微型数控加工厂家 适配价格需求 高性价比参考 - 甄选测评官
  • Cesium Terrain Builder:地形瓦片生成技术突破与3D地理可视化应用方案
  • C++高性能编程:从底层原理到游戏引擎开发的实战指南
  • Python 3.10与PyCharm 2021.2企业级开发环境搭建与配置实战
  • Python for...else语法深度解析:从原理到实战应用
  • HoRain云--Maven 项目模板
  • DSL到Vue代码转换:构建低代码平台核心引擎的设计与实现
  • 适合企业行政做会议纪要整理的2026年5款会议总结工具测评
  • 新乡的朋友看过来!查档案存放地很简单,教你一招,足不出户立马查清! - 实时传讯
  • 【C++算法】二分查找 -> 入门
  • 2026 企业级地址解析服务商选型指南
  • 基于OIDC实现GitHub Actions免密安全部署至阿里云OSS
  • 3步搞定抖音无水印下载:开源douyin_downloader工具终极指南
  • 数据血缘落地实战:从技术选型到运营闭环的完整指南
  • 2026年最新测厚仪/电磁超声检测设备/脉冲涡流检测设备生产厂家核心竞争力解构 - 青岛科瑞富有潜力 - 小范同学a
  • 手把手教你学 Simulink—— 基于扩展卡尔曼滤波(EKF)的整流器状态估计与故障预测仿真
  • 当 human in the loop 变成“闭着眼睛点确认”,企业Agent 安全还能靠谁?
  • 爬虫怎么批量采集完成任务
  • NS-Scope:释放泰克TDS示波器潜力,实现高精度数据采集与自动化测试