完美整数

57 阅读5分钟

题目解析

这道题的目的是判断给定区间 [x,y][x,y] 中有多少个整数是完美整数。一个整数被定义为完美整数的条件是,它的所有数字必须相同。例如,111333 是完美整数,而 1210119 不是。目标是计算区间中满足这个条件的所有整数的个数。


问题分解

  1. 什么是完美整数
    完美整数的关键特征是其数字构成的唯一性:

    • 如果一个数的所有数字都相同,它是完美整数。
    • 例如:
      • 1: 只有一个数字,自然是完美整数。
      • 11: 两个数字,且相同,是完美整数。
      • 333: 所有数字为 3,是完美整数。
      • 12: 数字不同,不是完美整数。
  2. 区间定义
    问题要求在区间 [x,y][x,y] 中找到所有的完美整数。注意以下情况:

    • 如果 x=yx=y,区间只有一个数,直接判断这个数是否完美。
    • 如果 x>yx>y,区间无效,结果为 0
    • 如果 x<yx<y,需要遍历区间中的每个整数,并逐一判断其是否满足完美整数的条件。
  3. 判断完美整数的规则

    • 将数字转化为字符串。
    • 检查字符串中的所有字符是否相同。如果所有字符相同,则该数字是完美整数。
  4. 完美整数的生成规律
    从数学的角度看,完美整数的分布具有一定规律:

    • 单位数范围内(1 至 9),所有数字都是完美整数。
    • 两位数范围内,完美整数只有 112233 等形式,数量为 9
    • 三位数范围内,完美整数包括 111222333 等形式,数量仍为 9
    • 一般而言,对于任意位数 dd 的范围,其完美整数形式数量固定为 9

    这意味着可以通过构造完美整数的方式高效地解决问题,而无需遍历所有整数。


解题思路

  1. 暴力枚举

    • 遍历区间 [x,y][x,y] 中的每个整数,逐个判断是否是完美整数。
    • 将数字转化为字符串,检查每个字符是否都相同。

    优点:

    • 简单直观,容易实现。

    缺点:

    • 当区间长度很大时效率较低,例如 x=1,y=106x=1,y=106。
  2. 优化策略

    • 使用完美整数的生成规律避免逐个判断:
      • 在单位数范围内,所有数字都是完美整数。
      • 在两位数范围内,只需要生成 1122、...、99
      • 在三位数范围内,只需要生成 111222、...、999
    • 利用数学公式构造完美整数:
      • 对于任意位数 dd,完美整数可以用公式表示:n×(10k−1)/9n×(10k−1)/9,其中 nn 是 11 到 99。

    优点:

    • 不需要遍历区间中的每个整数,生成方式更高效。
    • 当区间较大时,显著减少了不必要的计算。
  3. 步骤总结

    • 如果 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

时间复杂度分析

  1. 暴力枚举

    • 对区间 [x,y][x,y] 中每个整数进行字符串比较,时间复杂度为 O((y−x+1)×d)O((y−x+1)×d),其中 dd 是数字的位数。
    • 对于较大区间,性能可能无法满足要求。
  2. 优化策略

    • 通过生成规律,仅对有限的完美整数进行筛选:
      • 单位数和两位数范围固定为常数操作。
      • 高位数范围内完美整数的数量随位数增加而增大,但其生成和判断过程仍为常数操作。
    • 总体复杂度约为 O(log⁡10(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);
}

} `

总结

这道题利用完美整数的生成规律可以大幅减少判断次数,尤其是当区间较大时。优化策略避免了暴力枚举带来的低效操作,是解决该问题的关键。在实际应用中,可根据区间范围灵活选择暴力法或生成法,以实现更高效的解法。