news 2026/8/12 17:18:30

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 的数字)

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

如何用wxlivespy构建企业级微信视频号直播数据监控系统

如何用wxlivespy构建企业级微信视频号直播数据监控系统 【免费下载链接】wxlivespy 微信视频号直播间弹幕信息抓取工具 项目地址: https://gitcode.com/gh_mirrors/wx/wxlivespy 在直播电商和内容创作蓬勃发展的今天&#xff0c;微信视频号直播已成为商家、创作者和品牌…

作者头像 李华
网站建设 2026/8/12 17:17:01

Steam游戏自动破解:如何快速实现离线游戏完整指南

Steam游戏自动破解&#xff1a;如何快速实现离线游戏完整指南 【免费下载链接】Steam-auto-crack Steam Game Automatic Cracker 项目地址: https://gitcode.com/gh_mirrors/st/Steam-auto-crack 你是否曾因网络问题无法启动Steam游戏&#xff1f;或者希望在旅行时享受已…

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

Android SQLite数据库开发实战:从SQLiteOpenHelper到DAO模式完整指南

1. 项目概述与核心价值 在移动应用开发中&#xff0c;数据持久化是绕不开的核心环节。无论是记录用户的偏好设置、缓存网络请求结果&#xff0c;还是构建一个功能完整的笔记、记账类应用&#xff0c;都需要一个可靠、轻量且与平台深度集成的本地数据库方案。对于Android开发者而…

作者头像 李华
网站建设 2026/8/12 17:14:18

网站建设与管理复习知识点:资深运维人揭秘网站全生命周期核心奥秘与避坑指南

在这个互联网渗透进每一个毛孔的时代,网站早已不再仅仅是一个展示企业形象的静态页面,它更是品牌资产的数字化容器、用户交互的核心阵地以及商业转化的关键漏斗。如果你正在备考相关认证,或者刚刚接手了一家公司的网站运维工作,甚至只是对这一块内容充满好奇,那么这篇内容…

作者头像 李华
网站建设 2026/8/12 17:13:01

探索眉山建设中等职业技术学校网站:学子升学与就业的双重机遇指南,解读民办职业教育新标杆

在当前的教育大环境下,越来越多的家庭开始重新审视职业教育的价值。曾经,很多人对中职学校抱有偏见,认为那是“差生”的收容所,是学业失败后的无奈选择。然而,随着产业结构的升级和技能型人才的短缺,情况正在发生翻天覆地的变化。如今,选择一所优质的中等职业技术学校,…

作者头像 李华
网站建设 2026/8/12 17:10:31

维普论文AI检测降重策略与语义重构技术详解

1. 论文查重现状与痛点分析 论文查重是每个学术研究者必须面对的关卡&#xff0c;而维普作为国内主流查重系统之一&#xff0c;其AI检测功能让不少学生和研究者头疼。最近遇到一位研究生&#xff0c;他的论文初稿在维普系统检测出62%的AI率&#xff0c;这意味着超过一半内容被判…

作者头像 李华