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

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

根据之前搜索到的题目描述和解题思路,我直接为你编写 Go 实现。

LeetCode 3883 - Count Non Decreasing Arrays With Given Digit Sums (Go)

解题思路

1. 预处理:枚举 `[0, 5000]` 中每个数字,按其数位和分组
2. 动态规划 + 前缀和优化:`dp[j]` 表示前一个位置选择第 `j` 个候选数字的方案数,用前缀和加速"非递减"约束的转移

```go
package main

import (
"sort"
)

const MOD = 1_000_000_007

func countArrays(digitSum []int) int {
n := len(digitSum)

// 预处理:按数位和分组,收集 [0, 5000] 中的数字
// digitSum[i] <= 50,所以只需要 0~50 的分组
candidates := make([][]int, 51)
for num := 0; num <= 5000; num++ {
s := digitSumOf(num)
if s <= 50 {
candidates[s] = append(candidates[s], num)
}
}

// 如果某个位置没有候选数字,直接返回 0
for _, s := range digitSum {
if len(candidates[s]) == 0 {
return 0
}
}

// 确保每个分组都是有序的(由于按 num 顺序添加,已经有序)
for i := range candidates {
sort.Ints(candidates[i])
}

// 初始化第一个位置:每个候选数字都是一种方案
first := candidates[digitSum[0]]
dp := make([]int, len(first))
for i := range dp {
dp[i] = 1
}

// 处理后续每个位置
for i := 1; i < n; i++ {
prev := candidates[digitSum[i-1]]
curr := candidates[digitSum[i]]

// 计算 dp 的前缀和
prefix := make([]int, len(prev))
prefix[0] = dp[0]
for j := 1; j < len(prev); j++ {
prefix[j] = (prefix[j-1] + dp[j]) % MOD
}

newDp := make([]int, len(curr))

// 双指针:对于当前每个候选,找到所有 <= 它的 prev 候选
p := 0
for j := 0; j < len(curr); j++ {
currVal := curr[j]
for p < len(prev) && prev[p] <= currVal {
p++
}
// prev[0..p-1] 都 <= currVal
if p > 0 {
newDp[j] = prefix[p-1]
}
}

dp = newDp
}

// 统计所有方案
ans := 0
for _, v := range dp {
ans = (ans + v) % MOD
}
return ans
}

// 计算数字的数位和
func digitSumOf(num int) int {
sum := 0
for num > 0 {
sum += num % 10
num /= 10
}
return sum
}
```

关键点说明

要点 说明
预处理 枚举 `0~5000`,按数位和 `0~50` 分组,每组最多约 100 个数字
双指针优化 两个候选列表都是有序的,用双指针在 O(\|prev\| + \|curr\|) 内完成转移
前缀和 `prefix[j]` 表示 `dp[0..j]` 的和,快速求"所有合法前驱的方案数之和"
空间优化 只保留一维 DP,空间复杂度 O(m),m 为候选数字数量

复杂度

- 时间:O(n × m),n ≤ 1000,m 为每组候选数数量
- 空间:O(m)

示例验证

- `digitSum = [25, 1]` → 输出 `6`(799/889/898/979/988/997 后面接 1000)
- `digitSum = [1]` → 输出 `4`(1, 10, 100, 1000)
- `digitSum = [2, 49, 23]` → 输出 `0`(49 在 [0,5000] 内无数位和为 49 的数字)

http://www.cnnetsun.cn/news/3984599.html

相关文章:

  • 如何用wxlivespy构建企业级微信视频号直播数据监控系统
  • Steam游戏自动破解:如何快速实现离线游戏完整指南
  • Android SQLite数据库开发实战:从SQLiteOpenHelper到DAO模式完整指南
  • 网站建设与管理复习知识点:资深运维人揭秘网站全生命周期核心奥秘与避坑指南
  • 探索眉山建设中等职业技术学校网站:学子升学与就业的双重机遇指南,解读民办职业教育新标杆
  • 维普论文AI检测降重策略与语义重构技术详解
  • 当 human in the loop 变成“闭着眼睛点确认”,企业Agent 安全还能靠谁?
  • [光学原理与应用-500]:
  • 语言如何泄露思维模式:从词汇、句法到隐喻的认知分析
  • 多传感器融合SLAM:硬触发同步与RTK技术攻克长廊定位难题
  • Redis 不是万能存储:BigKey、消息可靠性与缓存一致性
  • 【2026最新】Python 安装教程(超详细图文版):从下载到安装一部到位
  • 计算机组成原理核心考点解析:Cache、流水线与复习策略
  • C++五子棋游戏开发:含禁手规则与AI实现详解
  • 网络爬虫技术深入探索——基于Python的实例解析与实战应用
  • 一个 NoSuchMethodError 查了 4 小时:双亲委派‘先问爹’的机制,让新 jar 永远赢不了老 jar
  • PCIe Gen6与EDSFF如何重塑数据中心存储架构
  • 从亚马逊得州天然气电厂事件,看AI算力狂潮下的绿色软件工程实践
  • 高性能macOS GUI应用架构解析:Applite如何实现Homebrew Casks的图形化管理
  • 适合企业行政做会议纪要整理的2026年5款会议总结工具测评
  • 自定义向量函数实现Qdrant批量数据向量化写入
  • 大文件分片上传与内容安全:从趣味体验到生产级解决方案
  • 红蓝对抗先写边界:允许动作、停止条件与报告路径
  • AI绘画API本地化部署:从Ollama到ComfyUI的免费生图方案
  • LangChain 1.x 工程化实践:从 LLM 调用到智能体与 RAG 应用开发
  • 如何轻松实现Palworld游戏存档数据转换:面向普通玩家的完整指南
  • C语言控制结构原理与性能优化实战
  • 解决Real-SR项目Vulkan初始化失败:vkCreateInstance错误-9的完整排查指南
  • C++实现PBR渲染管线:从数据流设计到性能优化的核心要点
  • 基于LLM的Query2doc技术:用大语言模型增强信息检索效果