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

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

这道题的核心是数位DP (Digit DP),直接枚举区间内的每个数字会超时。代码实现可以直接参考 LeetCode 官方题解区或 GitHub 上的高票答案。

📝 问题回顾

· 波动值 (Waviness):一个数字中峰(严格大于两边)和谷(严格小于两边)的总数。
· 规则:首尾数字不算;少于3位的数字波动值为0。
· 目标:返回区间 [num1, num2] 内所有数字波动值之和。

🧠 核心思路:数位DP (Digit DP)

利用前缀和思想 f(num) 计算 [0, num] 的总波动值,答案即为 f(num2) - f(num1 - 1)。

数位DP通过状态压缩避免枚举每个数字,核心DP状态通常包含:

· pos:当前处理到第几位。
· lastDigit / prevDigit:前一位或前两位的数字(用于判断峰谷)。
· lastDir:前两位数字的大小关系(上升/下降/相等)。
· tight:当前前缀是否和上限 num 的前缀完全一致(决定当前位上限)。
· started:是否已经开始填数字(用于处理前导零)。

💻 Python3 代码实现

```python
class Solution:
def totalWaviness(self, num1: int, num2: int) -> int:
# 辅助函数:计算 [0, num] 内所有数字的波动值之和
def count_upto(num: int) -> int:
if num < 100: # 少于3位,波动值均为0
return 0

digits = list(map(int, str(num)))
n = len(digits)

from functools import lru_cache

# 比较两个数字的大小关系,用于判断峰谷
# 返回: -1 下降, 0 相等, 1 上升
def cmp(a: int, b: int) -> int:
if a < b:
return 1
if a == b:
return 0
return -1

@lru_cache(None)
def dfs(pos: int, prev2: int, prev1: int, started: bool, tight: bool) -> (int, int):
# 返回: (从当前状态能构造出的数字个数, 这些数字的波动值总和)
if pos == n:
# 如果从未开始(即数字0),个数为1,波动值为0
return (1, 0) if started else (0, 0)

limit = digits[pos] if tight else 9
total_count = 0
total_waviness = 0

for d in range(0, limit + 1):
n_started = started or d != 0
n_tight = tight and (d == limit)

if not n_started:
# 仍然是前导零,prev1和prev2无意义,用 -1 占位
cnt, wav = dfs(pos + 1, -1, -1, False, n_tight)
else:
if not started:
# 刚结束前导零,当前是第一个有效数字,无法判断峰谷
cnt, wav = dfs(pos + 1, -1, d, True, n_tight)
else:
# 已有至少一个有效数字,可以尝试判断峰谷
add = 0
# 当 prev2 也存在时(即至少有3个有效数字),判断 prev1 是否为峰或谷
if prev2 != -1:
if (prev2 < prev1 > d) or (prev2 > prev1 < d):
add = 1
cnt, wav = dfs(pos + 1, prev1, d, True, n_tight)
wav += add * cnt # 当前位判断产生的波动值,贡献给所有后续构造出的数字

total_count += cnt
total_waviness += wav

return (total_count, total_waviness)

# 从最高位开始DFS,初始时未开始(started=False),处于受限状态(tight=True)
return dfs(0, -1, -1, False, True)[1]

# 利用前缀和思想,计算区间 [num1, num2] 的结果
return count_upto(num2) - count_upto(num1 - 1)
```

⏱️ 复杂度分析

· 时间复杂度:约为 O(log N * 10 * 状态数),其中 N 是 num2。状态数(pos, prev1, prev2, started, tight)是常数级别,因此效率很高。
· 空间复杂度:O(状态数),用于存储记忆化搜索的缓存。

✅ 测试示例

```python
sol = Solution()
print(sol.totalWaviness(120, 130)) # 输出: 3
print(sol.totalWaviness(198, 202)) # 输出: 3
print(sol.totalWaviness(4848, 4848)) # 输出: 2
```

这段代码通过数位DP高效地统计了所有数字的波动值总和,可以处理 num2 高达 10^15 的情况。

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

相关文章:

  • 从“今日头条”商标案看品牌保护:大厂的商标布局有多重要?
  • 调压变压器源头厂家哪家靠谱?采购实战指南 - 热点品牌推荐
  • Anki Cloze填空进阶指南:掌握嵌套标记与图像遮挡的深度应用
  • 想找靠谱液压工具源头工厂怎么联系 实用对接操作指南 - 热点品牌推荐
  • 【2026-07-27】待领养宠物信息汇总(发布于微信小程序:易领宠)
  • 港科大EMBA全球排第几?民营企业家择校选择指南
  • 2026年轿厢式别墅梯生产商业内推荐实用选型指南 - 热点品牌推荐
  • 清花1990|杏花村核心产区纯粮口粮酒,自饮送礼双适配 - 优企甄选
  • 选购不锈钢电缆桥架厂家需关注技术实力与行业经验 - 热点品牌推荐
  • HarmonyOS应用开发实战:猫猫大作战-NavPathStack 的完整 API 方法、生命周期关联、参数传递技巧,以及基于 NavPathStack
  • 2026年广东本色PEI板批发厂家采购实用测评参考 - 热点品牌推荐
  • 洛阳正规的二手选矿设备回收 贴心解决旧矿山设备处置难题 - 热点品牌推荐
  • DeepSeek LeetCode 3753. 范围内总波动值 II JavaScript实现
  • 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 开源发布!