区间内完美整数的数量计算
问题描述
完美整数是指由相同的数字构成的整数,例如:
- 完美整数示例:1、11、333
- 非完美整数示例:12、19、101
现要求在给定区间 ([x, y]) 中,统计所有完美整数的数量。
例如:
- 区间 ([1, 10]) 中,完美整数包括 1 到 9,总共有 9 个。
- 区间 ([2, 22]) 中,完美整数包括 2 到 9,以及 11 和 22,总共有 10 个。
输入格式
每个输入包括两个整数 (x) 和 (y):
- (x) 表示区间起始值;
- (y) 表示区间结束值;
- 数据范围:(1 \leq x \leq y \leq 10^9)。
输出格式
输出一个整数 (m),表示区间内的完美整数数量。
分析问题
完美整数的构造
完美整数的定义非常明确:每个数位的数字完全相同。我们可以通过以下规律构造所有可能的完美整数:
-
单位数字生成:
- 每个完美整数是由一个单位数字(1 到 9)重复多次构成。
- 例如,数字 2 可以生成 2, 22, 222, 2222 等。
-
范围限制:
- 在构造完美整数时,需要限制在 ([x, y]) 区间内的数字才能计入结果。
- 超出范围的数字无需计算,直接跳过。
完美整数的特性
由于完美整数本身结构简单,我们可以直接生成这些整数而无需遍历所有区间的数字,这使得计算过程更加高效。
解题思路
暴力方法的缺点
在区间较小时(例如 (x = 1, y = 100)),可以直接遍历所有数字,判断每个数字是否为完美整数。然而,当 (x, y) 接近 (10^9) 时,直接遍历区间会导致效率极低,甚至超出计算能力。
优化方法
通过观察发现:
- 直接从每个数字(1 到 9)出发,逐步生成完美整数;
- 对每个生成的整数,判断是否在区间 ([x, y]) 中。
核心步骤
-
遍历基础数字 (d)(从 1 到 9):
- 将 (d) 作为单位数字,从 1 位开始生成完美整数;
- 生成过程是递增的,每次增加一个数字位;
- 例如:对于 (d = 2),生成序列为 2, 22, 222, 2222...
-
检查范围限制:
- 如果生成的数字 (n) 超过区间上限 (y),停止当前序列;
- 如果 (n) 在 ([x, y]) 内,计入结果。
-
重复以上过程,直到所有可能的数字 (d) 都被处理完成。
优势
这种方法避免了直接遍历区间的巨大开销,仅生成符合完美整数定义的数字,时间复杂度大幅降低。
代码实现
以下是具体的 Java 实现代码:
public class Main {
public static int solution(int x, int y) {
int count = 0;
// 构造完美整数
for (int digit = 1; digit <= 9; digit++) { // 遍历每个可能的数字
long num = digit; // 初始为单个数字
while (num <= y) { // 构造完美整数直到超出范围
if (num >= x) {
count++;
}
num = num * 10 + digit; // 构造下一个完美整数
}
}
return count;
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(1, 10)); // 输出 9
System.out.println(solution(2, 22)); // 输出 10
System.out.println(solution(100, 999)); // 输出 27
System.out.println(solution(1, 1000000000)); // 测试最大范围
}
}
示例解析
示例1
输入:
x = 1, y = 10
处理过程:
- 单位数字生成:1, 2, ..., 9;
- 检查范围:所有生成的数字都在区间内。
结果:
9
示例2
输入:
x = 2, y = 22
处理过程:
- 单位数字生成:2, 3, ..., 9, 11, 22;
- 检查范围:所有生成的数字都符合条件。
结果:
10
示例3
输入:
x = 100, y = 999
处理过程:
- 单位数字生成:111, 222, ..., 999;
- 检查范围:所有生成的数字都在区间内。
结果:
27
时间复杂度分析
假设区间长度为 (L = y - x + 1):
- 基础数字循环:仅需遍历 9 个基础数字;
- 完美整数生成:每个基础数字最多生成 (\log_{10}y) 个完美整数。
因此,总体时间复杂度为: [ O(9 \cdot \log_{10}y) ]
在最坏情况下((y = 10^9)),(\log_{10}y \approx 9),计算效率非常高。
总结
本题通过对完美整数的定义和特性的深入分析,设计了一种基于 直接生成 的优化算法,有效避免了大区间遍历的低效操作。通过这种方法,我们能够在极大范围内快速统计出完美整数的数量。这种思路不仅适用于该问题,也为类似问题提供了一种有效的解决模板。