题目解析
这道题的目的是判断给定区间 [x,y][x,y] 中有多少个整数是完美整数。一个整数被定义为完美整数的条件是,它的所有数字必须相同。例如,1、11、333 是完美整数,而 12、101、19 不是。目标是计算区间中满足这个条件的所有整数的个数。
问题分解
-
什么是完美整数
完美整数的关键特征是其数字构成的唯一性:- 如果一个数的所有数字都相同,它是完美整数。
- 例如:
1: 只有一个数字,自然是完美整数。11: 两个数字,且相同,是完美整数。333: 所有数字为3,是完美整数。12: 数字不同,不是完美整数。
-
区间定义
问题要求在区间 [x,y][x,y] 中找到所有的完美整数。注意以下情况:- 如果 x=yx=y,区间只有一个数,直接判断这个数是否完美。
- 如果 x>yx>y,区间无效,结果为
0。 - 如果 x<yx<y,需要遍历区间中的每个整数,并逐一判断其是否满足完美整数的条件。
-
判断完美整数的规则
- 将数字转化为字符串。
- 检查字符串中的所有字符是否相同。如果所有字符相同,则该数字是完美整数。
-
完美整数的生成规律
从数学的角度看,完美整数的分布具有一定规律:- 单位数范围内(
1至9),所有数字都是完美整数。 - 两位数范围内,完美整数只有
11、22、33等形式,数量为9。 - 三位数范围内,完美整数包括
111、222、333等形式,数量仍为9。 - 一般而言,对于任意位数 dd 的范围,其完美整数形式数量固定为
9。
这意味着可以通过构造完美整数的方式高效地解决问题,而无需遍历所有整数。
- 单位数范围内(
解题思路
-
暴力枚举
- 遍历区间 [x,y][x,y] 中的每个整数,逐个判断是否是完美整数。
- 将数字转化为字符串,检查每个字符是否都相同。
优点:
- 简单直观,容易实现。
缺点:
- 当区间长度很大时效率较低,例如 x=1,y=106x=1,y=106。
-
优化策略
- 使用完美整数的生成规律避免逐个判断:
- 在单位数范围内,所有数字都是完美整数。
- 在两位数范围内,只需要生成
11、22、...、99。 - 在三位数范围内,只需要生成
111、222、...、999。
- 利用数学公式构造完美整数:
- 对于任意位数 dd,完美整数可以用公式表示:n×(10k−1)/9n×(10k−1)/9,其中 nn 是 11 到 99。
优点:
- 不需要遍历区间中的每个整数,生成方式更高效。
- 当区间较大时,显著减少了不必要的计算。
- 使用完美整数的生成规律避免逐个判断:
-
步骤总结
- 如果 xx 和 yy 在单位数范围内,直接统计个数即可。
- 如果区间跨越了多个位数范围(例如 [5,150][5,150]),可以分段处理:
- 单位数范围:直接统计个数。
- 两位数范围:生成
11到99,统计在区间内的数字。 - 三位数范围:生成
111到999,统计在区间内的数字。
- 返回统计结果。
测试样例分析
样例 1
- 输入:
x = 1, y = 10 - 分析:
- 单位数范围内的所有数字都是完美整数。
- 完美整数为:
1, 2, 3, 4, 5, 6, 7, 8, 9。 - 数量为
9。
- 输出:
9
样例 2
- 输入:
x = 2, y = 22 - 分析:
- 单位数范围内的完美整数为:
2, 3, 4, ..., 9,共8个。 - 两位数范围内的完美整数为:
11, 22,共2个。 - 总数量为
8 + 2 = 10。
- 单位数范围内的完美整数为:
- 输出:
10
样例 3
- 输入:
x = 1, y = 100 - 分析:
- 单位数范围内的完美整数为:
1, 2, ..., 9,共9个。 - 两位数范围内的完美整数为:
11, 22, ..., 99,共9个。 - 总数量为
9 + 9 = 18。
- 单位数范围内的完美整数为:
- 输出:
18
时间复杂度分析
-
暴力枚举
- 对区间 [x,y][x,y] 中每个整数进行字符串比较,时间复杂度为 O((y−x+1)×d)O((y−x+1)×d),其中 dd 是数字的位数。
- 对于较大区间,性能可能无法满足要求。
-
优化策略
- 通过生成规律,仅对有限的完美整数进行筛选:
- 单位数和两位数范围固定为常数操作。
- 高位数范围内完美整数的数量随位数增加而增大,但其生成和判断过程仍为常数操作。
- 总体复杂度约为 O(log10(y))O(log10(y))。
- 通过生成规律,仅对有限的完美整数进行筛选:
` public class Main { public static boolean isPerfect(int num) { String numStr = Integer.toString(num); char firstChar = numStr.charAt(0);
// 检查是否所有的字符都相同
for (int i = 1; i < numStr.length(); i++) {
if (numStr.charAt(i) != firstChar) {
return false;
}
}
return true;
}
public static int solution(int x, int y) {
int count = 0;
// 遍历区间中的每个整数,判断是否是完美整数
for (int i = x; i <= y; i++) {
if (isPerfect(i)) {
count++;
}
}
return count;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(solution(1, 10) == 9);
System.out.println(solution(2, 22) == 10);
}
} `
总结
这道题利用完美整数的生成规律可以大幅减少判断次数,尤其是当区间较大时。优化策略避免了暴力枚举带来的低效操作,是解决该问题的关键。在实际应用中,可根据区间范围灵活选择暴力法或生成法,以实现更高效的解法。