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

DeepSeek LeetCode 3753. 范围内总波动值 II JavaScript实现

对于 LeetCode 3753 这道困难题,核心解法是数位 DP,配合前缀和技巧:F(num2) - F(num1-1)。以下是基于该思路的 JavaScript 实现。

```javascript
/**
* @param {number} num1
* @param {number} num2
* @return {number}
*/
var totalWaviness = function(num1, num2) {
const countUpTo = (x) => {
if (x < 100) return 0; // 少于3位数,波动值为0

const digits = String(x).split('').map(Number);
const n = digits.length;
// 记忆化缓存,key编码为字符串
const memo = new Map();

// pos: 当前处理位置, prev2: 前两位数字(-1表示不存在), prev1: 前一位数字(-1表示不存在), tight: 是否受到上界限制, started: 是否已经开始构造有效数字
const dfs = (pos, prev2, prev1, tight, started) => {
if (pos === n) {
return { count: 1, sum: 0 };
}

const key = `${pos},${prev2},${prev1},${tight},${started}`;
if (memo.has(key)) return memo.get(key);

const limit = tight ? digits[pos] : 9;
let totalCount = 0;
let totalSum = 0;

for (let d = 0; d <= limit; d++) {
const nextTight = tight && (d === limit);
const nextStarted = started || d !== 0;

// 仍然是前导零的情况:数字还未开始
if (!nextStarted) {
const res = dfs(pos + 1, -1, -1, nextTight, false);
totalCount += res.count;
totalSum += res.sum;
continue;
}

// 构造当前数字的三元组:prev2, prev1, d
let add = 0;
if (started && prev2 !== -1 && prev1 !== -1) {
// 判断 prev1 是否为峰或谷
if ((prev1 > prev2 && prev1 > d) || (prev1 < prev2 && prev1 < d)) {
add = 1;
}
}

const nextPrev2 = prev1;
const nextPrev1 = d;
const res = dfs(pos + 1, nextPrev2, nextPrev1, nextTight, true);

totalCount += res.count;
// 当前位对总和的贡献:如果当前构成波动,则后续每一种补全方式都贡献1
totalSum += res.sum + add * res.count;
}

const result = { count: totalCount, sum: totalSum };
memo.set(key, result);
return result;
};

// 返回 [0, x] 的总波动值
return dfs(0, -1, -1, true, false).sum;
};

// 前缀和思想:区间和 = F(num2) - F(num1-1)
return countUpTo(num2) - countUpTo(num1 - 1);
};
```

核心思路

1. 数位 DP + 容斥:分别计算 [0, num2] 和 [0, num1-1] 的总波动值,相减得到区间 [num1, num2] 的结果。
2. 状态设计:判断一个数字是否为峰/谷,需要知道它的前两位数字 prev2 和 prev1,因此将它们作为 DFS 的状态参数。此外还需:
· tight:是否紧贴上界,用于控制枚举上限。
· started:是否已经开始构造有效数字,用于处理前导零。
3. 贡献累加:在 DFS 过程中,每当我们确定一位数字 d 并发现它与 prev2、prev1 构成峰/谷时,不仅累加自身的 1,还要累加当前波动值 * 后续所有可能的补全方式数量,从而一次性统计所有合法数字的贡献。

复杂度

· 时间复杂度:O(log N * 10^2 * 2 * 2 * 10),即 O(400 * log N),其中 N 是 num2 的值。
· 空间复杂度:O(log N * 400),用于记忆化缓存。

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

相关文章:

  • HarmonyOS应用开发实战:猫猫大作战-Tabs 的声明式用法、自定义 TabBar 样式、事件监听和性能优化
  • 人脸修复耗时超8分钟?优化GPU显存占用与推理加速的7个硬核技巧(附TensorRT部署实测数据)
  • 教你几招:京东外卖优惠券手机免费领的秘诀 - 工具软件使用方法推荐
  • RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!
  • 多无人机协同路径规划:基于多段Dubins路径的Matlab实现
  • 旅行准备必读:2026年酒店预订省钱攻略大全 - 工具软件使用方法推荐
  • 通州区厕所漏水维修哪家靠谱?本地老师傅推荐这家 - 热点品牌推荐
  • 港科大EMBA师资解析,民营企业家择校选择指南
  • RISC-V IOMMU 硬件设计学习计划|第 1 天:IOMMU 在 RISC-V SoC 中解决什么问题
  • 教你如何在2026年找到性价比高的酒店 - 工具软件使用方法推荐
  • 地下水数值模拟软件Visual modflow Flex实践技术应用
  • Python计算机毕设之基于Python的数字化智能停车场综合运维系统设计 基于 B/S 架构的智能停车服务管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • DeepSeek LeetCode 3753. 范围内总波动值 II Java实现
  • 2026 年沿河土家族自治热门的铅衣平台哪家可靠,拍胸片时穿的那件“铁马甲”,居然藏着你不知道的辐射防护猫腻?-汇生新型建材 - 行业甄选官
  • 揭秘秘塔AI学术搜索底层逻辑:3步实现文献查全率提升47%的实战方法
  • 2026年靠谱的环保除油剂厂商有哪些实用选型参考指南 - 热点品牌推荐
  • 【电赛上分利器】用 AI 零代码配置 TI MSPM0?天猛星 MSPM0G3507 专属 Agent Skill 开源发布!
  • 2026年挑选可靠休闲食品油炸生产线工厂实用参考指南 - 热点品牌推荐
  • LangChain 表达式语言 (LCEL):从序列链接到并行执行
  • 抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽
  • 动图转视频原来这么简单 2026手把手教程 - 软件工具教程方法
  • Python计算机毕设之 基于 Python 的毕业生就业动态追踪系统智慧校园毕业生就业信息采集管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • TPS65982BB芯片解析:集成USB Billboard、数据MUX与5V负载开关的设计指南
  • 如何将Codex、Claude Code等多个AI Agent组合起来,搭建一个能协同工作、自动执行复杂任务的一套可迁移到任何课题的“AI科研团队”。
  • 教你如何巧妙领取外卖优惠券,享受更多优惠 - 工具软件使用方法推荐
  • 抖音批量下载器完整教程:三步免费获取无水印视频
  • 旅行省钱小窍门:2026年最佳酒店预订软件盘点 - 工具软件使用方法推荐
  • 深度解析:mac-precision-touchpad如何让苹果触控板在Windows上获得原生级体验
  • 2026年精密裁切水口机生产厂家哪家靠谱实测解析 - 热点品牌推荐
  • 找璧山厂房耐磨固化地坪厂家 靠谱筛选攻略帮你少走弯路 - 热点品牌推荐