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

DeepSeek LeetCode 2338.统计理想数组的数目 JavaScript实现

这是 LeetCode 2338「统计理想数组的数目」的 JavaScript 实现,主要利用质因数分解 + 组合数学(隔板法)来解决。

```javascript
/**
* @param {number} n
* @param {number} maxValue
* @return {number}
*/
const idealArrays = (n, maxValue) => {
const MOD = 1e9 + 7;
const limit = maxValue;

// 预处理组合数 C(n+k-1, k)
// 我们需要计算 C(n + len - 1, len)
// 因为 n 最大 1e4,这里 n + 最大指数和大约 2e4
const maxLen = 14; // 2^14 = 16384 > 1e4
const maxComputed = n + maxLen;

// 阶乘与逆元
const fact = new Array(maxComputed + 5);
const invFact = new Array(maxComputed + 5);
fact[0] = 1;
for (let i = 1; i <= maxComputed; i++) {
fact[i] = Number((BigInt(fact[i-1]) * BigInt(i)) % BigInt(MOD));
}

// 快速幂
const powMod = (a, b) => {
let res = 1n;
let base = BigInt(a);
let exp = b;
while (exp > 0) {
if (exp & 1) res = (res * base) % BigInt(MOD);
base = (base * base) % BigInt(MOD);
exp >>= 1;
}
return Number(res);
};

invFact[maxComputed] = powMod(fact[maxComputed], MOD-2);
for (let i = maxComputed-1; i >= 0; i--) {
invFact[i] = Number((BigInt(invFact[i+1]) * BigInt(i+1)) % BigInt(MOD));
}

const comb = (a, b) => {
if (b < 0 || b > a) return 0;
let res = BigInt(fact[a]) * BigInt(invFact[b]) % BigInt(MOD);
res = res * BigInt(invFact[a-b]) % BigInt(MOD);
return Number(res);
};

// 对 1..maxValue 做质因数分解,记录每个数的质因数分解(指数形式)
// 但是不需要所有数,我们只需要对于每个数分解为 p1^e1 * p2^e2 * ...
// 然后对于每个质因子的指数序列,求非递减序列个数 = C(n + len(e) - 1, len(e)),乘起来

let total = 0n;

// 预处理最小质因子,用于快速分解
const spf = new Array(limit + 1);
for (let i = 2; i <= limit; i++) {
if (!spf[i]) {
spf[i] = i;
for (let j = i*i; j <= limit; j += i) {
if (!spf[j]) spf[j] = i;
}
}
}
for (let i = 2; i <= limit; i++) {
if (!spf[i]) spf[i] = i;
}

// 对每个数分解质因数,得到指数数组
for (let num = 1; num <= limit; num++) {
let x = num;
const exponents = [];
while (x > 1) {
const p = spf[x];
let cnt = 0;
while (x % p === 0) {
x /= p;
cnt++;
}
exponents.push(cnt);
}
// 如果没有质因子(num=1),指数数组为空
// 对于空数组,C(n+0-1,0)=1
let ways = 1n;
for (const e of exponents) {
// 指数 e 在长度为 n 的数组中非递减(实际是递增,因为必须整除,但指数可以相等)
// 把 e 个相同的球放入 n 个盒子(允许空盒)=> C(n+e-1, e)
ways = ways * BigInt(comb(n + e - 1, e)) % BigInt(MOD);
}
total = (total + ways) % BigInt(MOD);
}

return Number(total);
};
```

核心思路

1. 问题转化
理想数组满足 arr[i] | arr[i+1](整除)。把每个数用质因数分解表示:
arr[i] = p1^{a_i1} p2^{a_i2} ...
则整除条件等价于每个质因子的指数序列是非递减的。
2. 独立计数
不同质因子独立,对于每个质因子的指数序列,长度为 n,从 0 到某个最大值 e(目标数的指数),求非递减序列个数。
这等价于:把 e 个相同小球放入 n 个盒子(允许空) = C(n+e-1, e)。
3. 组合数计算
n 最大 1e4,指数 e 最大约 log₂(maxValue) ≤ 14,因此 n+e-1 ≤ 10013,可直接预处理阶乘和逆元。
4. 遍历 1..maxValue
对每个数质因数分解,得到各质因子指数,将每个指数对应的组合数相乘,累加所有数的结果。

时间复杂度

· 预处理阶乘、逆元:O(n + log MOD)
· 每个数质因数分解:O(log maxValue)
· 总复杂度:O(maxValue log maxValue)

示例

```javascript
console.log(idealArrays(2, 5)); // 10
console.log(idealArrays(5, 3)); // 11
```

该解法能高效通过大数据范围约束。

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

相关文章:

  • Chiplet架构下的处理器性能优化与ARCAS系统解析
  • 2026贵阳配镜技术解析:苏州眼镜店/苏州配眼镜/西安配眼镜/贵阳眼镜店/贵阳配眼镜/郑州眼镜店/郑州配眼镜/重庆眼镜店/选择指南 - 优质品牌商家
  • ARM AMUv1架构解析与性能监控实战
  • 四度入围金曲歌王!裘德《离开银色荒原》荣获金曲奖7项提名
  • 使用 Node.js 和 Taotoken 快速搭建一个简单的 AI 对话中间件
  • 收藏!小白程序员必看:大模型时代高薪就业新机遇与学习路径
  • 流式Markdown解析器:实现实时渲染与性能优化的核心技术
  • 近屿AI学:基础薄弱还转AI,他真做成了
  • 学校知识竞赛怎么组织?从班级到年级的进阶方案
  • 8K 剪辑卡皇之争:RTX 4090 vs A6000 大显存显卡选型深度指南(下)
  • 2026浏览器插件扩展安全风险溯源与环境隔离防护规范
  • 当技术成为唯一身份标签:为什么你需要一个“非技术”爱好?
  • 从DenseNet到特征复用:揭秘密集连接如何重塑卷积网络
  • 在ubuntu服务器上快速配置taotoken的python调用环境
  • 从证伪主义到真学:论“贾子之路”的必然性与AI认知主权的重建——基于范式革命与多文明认知框架的深度研究
  • C-Eval中文基准测试到底准不准?3轮人工校验+5类对抗样本验证,真相令人震惊
  • 3-5年经验程序员注意:这3大岗位年薪飙升至百万,你中招了吗?
  • Claude + Nx + Angular:构建下一代可维护单体应用的4层AI增强架构(仅限首批内测团队公开)
  • 怎样轻松上手yuzu模拟器:3个实用技巧帮你快速畅玩Switch游戏
  • 工会知识竞赛活动策划:凝聚职工、寓教于乐
  • NCE外汇:全球化战略布局的多维考察
  • IT求职简历修改频率:多久更新一次更合适?
  • Instructure 向 Canvas 黑客支付赎金,数据虽归还但支付风险引担忧
  • 电子围栏系统设计:基于基站定位的防疫隔离技术方案解析
  • 5步掌握RFSoC软件定义无线电:从零基础到实战开发的完整指南
  • 空间可计算・跨镜可连续:镜像视界NeRF+实时重构跟踪体系解决方案
  • 原创文档:溶剂热法制备NiCo-LDHs及其电催化析氧性能研究
  • Arm调试寄存器架构详解与应用实践
  • BambooAI:本地化AI数据分析助手,用自然语言驱动Pandas代码生成
  • 轻量级趋势数据采集分析工具:从零构建可插拔监控系统