题解:判断区间中的完美整数数量
问题描述
一个整数是完美整数,当且仅当它的所有位数都相同。例如:1、11、333 是完美整数,而 12、19、101 则不是。
我们需要计算区间 [x, y] 中所有完美整数的数量。
AC代码
public class Main {
public static int solution(int x, int y) {
// Edit your code here
int count = 0;
for(int i = x; i <= y; i++){
if (check(i)) {
count++;
}
}
return count;
}
private static boolean check(int x) {
String xs = Integer.toString(x);
char[] xc = xs.toCharArray();
char tmp = xc[0];
for (char c : xc) {
if (c != tmp) {
return false;
}
}
return true;
}
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);
}
}
代码分析
-
核心函数
solution(int x, int y)- 遍历区间
[x, y]中的每个整数i。 - 对每个
i调用辅助函数check(int x)检查是否为完美整数。 - 累计满足条件的整数个数并返回。
- 遍历区间
-
辅助函数
check(int x)- 将整数
x转为字符串,随后转为字符数组。 - 比较所有字符是否与第一个字符相同,若不相同返回
false,否则返回true。
- 将整数
-
测试用例
solution(1, 10),期望输出为 9,因为除 10 以外,其余均为完美整数。solution(2, 22),期望输出为 10,因为 [2, 22] 内所有个位和十位数字均相同的整数是:2、3、...、9、11、22。
时间复杂度
- 区间长度为
n = y - x + 1:- 对于每个数字调用
check(),其复杂度为O(d),其中d为数字位数。 - 因此总复杂度为
O(n * d)。
- 对于每个数字调用
- 若区间较大或数字位数较多,该实现效率较低。
改进方案
现有实现通过字符串和数组的转换来判断每个数的位是否相同,存在一定的开销。可以优化为 数学运算 或 直接生成完美整数 的方式,减少遍历和检查。
方案一:使用数学运算优化 check()
无需转换为字符串,可直接通过数值运算判断每一位是否相同:
private static boolean check(int x) {
int lastDigit = x % 10; // 获取最后一位
while (x > 0) {
if (x % 10 != lastDigit) {
return false; // 存在不同的数字
}
x /= 10; // 去掉最后一位
}
return true;
}
这种方式避免了字符串操作,直接基于整数运算实现,效率更高。
方案二:直接生成完美整数
完美整数具有规律性(如 1, 2, ..., 9, 11, ..., 99, 111...)。我们可以跳过所有非完美整数的判断,直接生成完美整数并检查是否在 [x, y] 范围内:
public static int solution(int x, int y) {
int count = 0;
for (int digit = 1; digit <= 9; digit++) {
int num = digit; // 初始为单个数字
while (num <= y) {
if (num >= x) {
count++;
}
num = num * 10 + digit; // 构造下一个完美整数
}
}
return count;
}
- 外层循环枚举数字
1~9作为重复数字。 - 内层循环构造完美整数(如
1, 11, 111...)并判断是否在[x, y]范围内。 - 跳过不必要的检查操作,复杂度降低到与区间内完美整数的数量相关。
改进的时间复杂度
- 构造完美整数最多需要生成每个位数的 9 个数字:
- 复杂度约为
O(log(y))。
- 复杂度约为
- 相较于暴力枚举
O(n * d),显著减少了非完美整数的计算。
总结
- 当前代码优点:逻辑清晰,适合小范围测试。
- 缺点:时间复杂度高,当区间较大或数字位数多时效率较低。
- 优化方向:
- 使用数学运算代替字符串操作(方案一)。
- 利用完美整数规律直接生成结果(方案二)。