Find Total Numbers with No Repeated Digits in A Range in Java

2025年5月8日 | 阅读 7 分钟

查找范围内没有重复数字的总数的问题涉及识别每个数字仅出现一次的数字。它有助于分析数字属性,并经常用于组合数学。这个概念对于解决与数字唯一性和优化相关的求解很有用。

示例 1

输入 5 15

输出 9

说明: 范围 5 到 15 中没有重复数字的数字是:5、6、7、8、9、10、12、13、14、15。

示例 2

输入 20 30

输出 9

说明: 范围 20 到 30 中没有重复数字的数字是:20、21、23、24、25、26、27、28、29。

方法:暴力法

暴力破解方法包括直接检查所有可能的解决方案或情况,而无需任何优化。它通常使用简单、直接的逻辑来解决问题,但对于大型输入而言,时间复杂度通常很高。

算法

步骤 1: 设置下界和上界,并将计数器 count 初始化为 0。

步骤 2: 定义 hasRepeatedDigits(num) 以使用数字跟踪 数组 检查数字是否包含重复数字。

步骤 3: 循环遍历从 lower 到 upper 的数字。

步骤 4: 如果数字没有重复的数字,则递增 count。

步骤 5: 打印给定范围内具有唯一数字的数字的数量。

实施

文件名:BruteForceUniqueDigits.java

输出

 
Range: 10 to 30
Total numbers with no repeated digits: 19   

方法:前缀和法

前缀和法涉及预先计算元素范围的累积和(或计数),以便能够进行高效的范围查询。

算法

步骤 1: 定义一个 hasRepeatedDigits() 方法,使用数组检查数字是否具有重复数字。

步骤 2: 创建一个前缀数组来存储 up to maxRange 的唯一数字的累积计数。

步骤 3: 通过对没有重复数字的数字加 1 来填充前缀数组,使用 hasRepeatedDigits。

步骤 4: 对于范围 [L, R],将唯一数字的计数计算为 prefix[R] - prefix[L - 1]。

步骤 5: 打印范围以及该范围内唯一数字的总数。

实施

文件名:EfficientUniqueDigits.java

输出

 
Range: 10 to 30
Total numbers with no repeated digits: 19   

动态规划

该方法使用带记忆化的动态规划,通过递归地探索所有数字位置来有效地计算具有唯一数字的数字。它使用位掩码跟踪可用数字,并处理前导零和每个数字的紧凑约束。

算法

步骤 1: 创建并初始化一个 4D 记忆化数组来存储中间结果。

步骤 2: 实现一个递归函数,根据位置、紧凑约束和可用数字来计算具有唯一数字的数字。

步骤 3: 如果所有数字都已处理,则为有效数字返回 1。

步骤 4: 循环遍历可能的数字,并进行递归调用以计算有效数字的计数。

步骤 5: 通过从 [0, upperBound] 的结果中减去 [0, lowerBound-1] 的结果来计算范围内具有唯一数字的数字的计数。

实施

文件名:UniqueDigitCounter.java

输出

 
The count of numbers with unique digits in the range 1 to 100 is: 98   

时间复杂度: O(log(R) × M),其中 M = 1024。

辅助空间复杂度: O(log(R) × M)。