news 2026/10/31 20:45:59

LeetCode 1012题解:数位DP计算重复数字问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 1012题解:数位DP计算重复数字问题

1. 问题解析:LeetCode 1012至少有1位重复的数字

这道题目要求我们计算从1到n的所有整数中,至少有一位数字重复出现的数字个数。这类问题在算法竞赛和面试中属于经典题型,主要考察数位动态规划(Digit DP)和组合数学的应用能力。

1.1 问题重述与转化

题目给出的函数签名为:

public int numDupDigitsAtMostN(int n)

直接计算"至少有一位重复"的数字数量比较困难,更聪明的做法是采用补集思想:

  • 总数:n本身
  • 无重复数字的数目:计算所有数字都不相同的数字个数
  • 结果 = 总数 - 无重复数字的数目

这种转化将问题简化为计算"所有数字都不相同"的数字个数,这正是数位DP擅长的领域。

1.2 数位DP基础概念

数位DP是一种专门用于解决数字各位上数字满足特定条件问题的动态规划方法。其核心思想是:

  1. 将数字按位拆分处理
  2. 记忆化已计算的状态
  3. 通过限制条件控制数字范围

对于本题,我们需要记录以下状态:

  • 当前处理到的数位位置
  • 已经使用的数字集合
  • 是否已经小于n的前缀(决定当前位的选择范围)

2. 解决方案设计与实现

2.1 组合数学解法

我们可以将问题分解为计算所有位数不超过n的数字中不含重复数字的数目。对于k位数,不含重复数字的数目计算如下:

  • 第一位:1-9(9种选择)
  • 第二位:0-9除去第一位(9种选择)
  • 第三位:0-9除去前两位(8种选择)
  • ...
  • 第k位:0-9除去前k-1位(10-(k-1)种选择)

因此,k位数中不含重复数字的数目为: 9 × 9 × 8 × ... × (10 - k + 1)

2.2 数位DP实现细节

以下是Java实现的详细解析:

public int numDupDigitsAtMostN(int n) { String s = String.valueOf(n); int len = s.length(); // 计算位数小于len的无重复数字数目 int total = 0; for (int i = 1; i < len; i++) { total += 9 * permutation(9, i - 1); } // 计算位数等于len的无重复数字数目 boolean[] used = new boolean[10]; for (int i = 0; i < len; i++) { int digit = s.charAt(i) - '0'; for (int j = (i == 0 ? 1 : 0); j < digit; j++) { if (!used[j]) { total += permutation(9 - i, len - i - 1); } } if (used[digit]) break; used[digit] = true; } // 加上n本身是否无重复 boolean noDup = true; for (int i = 0; i < 10; i++) { if (count[i] > 1) { noDup = false; break; } } if (noDup) total++; return n - total; } private int permutation(int n, int k) { if (k == 0) return 1; return n * permutation(n - 1, k - 1); }

2.3 关键步骤解析

  1. 数字转换:将n转换为字符串,便于逐位处理
  2. 小于位数的计算:对于所有位数小于n的数字,直接使用排列组合公式计算
  3. 等于位数的计算:
    • 从最高位开始处理
    • 对于每一位,考虑所有小于当前数字的选择
    • 使用used数组记录已经使用的数字
    • 计算剩余位的排列可能性
  4. 检查n本身:最后需要单独检查n是否不含重复数字

3. 复杂度分析与优化

3.1 时间复杂度

  • 数字n的位数为d=log10(n)
  • 排列计算的时间复杂度为O(d)
  • 总体时间复杂度为O(d^2)

3.2 空间复杂度

  • 只需要常数空间存储used数组
  • 递归深度为d
  • 总体空间复杂度为O(d)

3.3 优化方向

  1. 记忆化排列计算:可以预计算阶乘表,避免重复计算
  2. 迭代实现:改写递归为迭代,减少函数调用开销
  3. 位运算优化:使用位掩码代替boolean数组记录已用数字

4. 常见问题与调试技巧

4.1 边界条件处理

  • n=0时应该返回0
  • n<10时直接返回0(1-9都没有重复数字)
  • 注意数字首位不能为0的限制

4.2 调试技巧

  1. 小规模测试:从n=10开始逐步测试
  2. 中间输出:打印每一步的计算结果
  3. 对比验证:与暴力解法结果对比

提示:在面试中,可以先提出暴力解法,再优化为数位DP方案,展示思考过程。

5. 实际应用与变种

5.1 实际应用场景

这类问题在以下场景有实际应用:

  • 密码强度检测(限制重复数字)
  • 序列号生成(避免重复模式)
  • 数据压缩(利用数字唯一性)

5.2 相关变种题目

  1. 计算不含连续相同数字的数目
  2. 计算数字各位满足单调递增/递减的数目
  3. 计算包含特定数字模式的数目

6. 个人实现心得

在实际编码中,我发现以下几点特别重要:

  1. 数位处理顺序:从高位到低位处理更符合直觉
  2. 状态设计:合理设计状态表示(如used数组)是关键
  3. 排列计算:单独提取为函数提高代码可读性
  4. 边界检查:最后别忘记检查n本身

对于Java实现,使用String处理数字比数学运算更直观。在性能要求高的场景,可以改用数学方法处理数位。

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

Word文档分页符隐藏技巧与专业排版实践

1. Word文档分页符基础认知分页符是Word文档中最常用的排版控制符号之一&#xff0c;它的作用就像书本中的章节分隔页。当我们在文档中插入分页符时&#xff0c;Word会强制从当前位置开始新的一页&#xff0c;无论当前页面剩余多少空白区域。这个看似简单的功能&#xff0c;在实…

作者头像 李华
网站建设 2026/10/31 20:39:28

AWS、Azure与GCP三大云平台核心服务对比指南

1. 云计算三巨头服务全景对比当企业开始数字化转型时&#xff0c;选择云平台往往成为第一个关键决策。作为从业十余年的云架构师&#xff0c;我经常被问到&#xff1a;AWS、Azure和GCP究竟该如何选择&#xff1f;这三个平台各自的服务对应关系是怎样的&#xff1f;今天我们就来…

作者头像 李华
网站建设 2026/10/31 20:32:52

深入解析进程管理:从基础概念到实践优化

1. 进程基础概念解析在计算机科学领域&#xff0c;进程&#xff08;Process&#xff09;是操作系统资源分配的基本单位&#xff0c;也是程序执行的一个实例。当我们在Windows任务管理器或Linux的top命令中看到的各种运行中的程序&#xff0c;本质上都是进程的具体表现。每个进程…

作者头像 李华
网站建设 2026/10/31 20:30:46

TDengine与ProDB在石化行业时序数据处理中的优化实践

1. 项目背景与挑战&#xff1a;石化行业的数据洪流在石油化工行业&#xff0c;每分钟都有数以万计的数据点从反应釜、管道、储罐和各类传感器中喷涌而出。泰州石化作为华东地区重要的炼化一体化企业&#xff0c;其生产装置每天产生的数据量相当于一个小型城市的所有物联网设备总…

作者头像 李华
网站建设 2026/10/31 20:23:56

Oracle 19c SQL函数避坑:日期边界、NULL与分析函数实践

简介&#xff1a;Oracle 19c SQL语言参考手册PDF文档&#xff0c;面向Oracle数据库开发者、DBA及备考OCP/OCA的技术人员&#xff0c;针对日常SQL编写时函数用法记不全、参数含义模糊、类型转换与日期计算易出错等问题&#xff0c;提供官方权威速查依据。资源为1个PDF文件&#…

作者头像 李华
网站建设 2026/10/31 20:19:44

信息安全管理与评估赛项环境搭建:从设备配置到攻防复现的完整指南

简介&#xff1a;这份PDF是2015年全国职业院校技能大赛高职组“神州数码”杯信息安全管理与评估赛项的官方任务书&#xff0c;面向备赛的高职院校选手、指导教师以及信息安全实训学习者&#xff0c;可用于还原赛场任务、开展专项训练与教学演练。资源包共1个PDF文件&#xff0c…

作者头像 李华