每天一小步 | 豆包MarsCode AI刷题

132 阅读4分钟

区间内完美整数的数量计算

问题描述

完美整数是指由相同的数字构成的整数,例如:

  • 完美整数示例: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. 单位数字生成

    • 每个完美整数是由一个单位数字(1 到 9)重复多次构成。
    • 例如,数字 2 可以生成 2, 22, 222, 2222 等。
  2. 范围限制

    • 在构造完美整数时,需要限制在 ([x, y]) 区间内的数字才能计入结果。
    • 超出范围的数字无需计算,直接跳过。

完美整数的特性

由于完美整数本身结构简单,我们可以直接生成这些整数而无需遍历所有区间的数字,这使得计算过程更加高效。


解题思路

暴力方法的缺点

在区间较小时(例如 (x = 1, y = 100)),可以直接遍历所有数字,判断每个数字是否为完美整数。然而,当 (x, y) 接近 (10^9) 时,直接遍历区间会导致效率极低,甚至超出计算能力。

优化方法

通过观察发现:

  • 直接从每个数字(1 到 9)出发,逐步生成完美整数;
  • 对每个生成的整数,判断是否在区间 ([x, y]) 中。
核心步骤
  1. 遍历基础数字 (d)(从 1 到 9):

    • 将 (d) 作为单位数字,从 1 位开始生成完美整数;
    • 生成过程是递增的,每次增加一个数字位;
    • 例如:对于 (d = 2),生成序列为 2, 22, 222, 2222...
  2. 检查范围限制:

    • 如果生成的数字 (n) 超过区间上限 (y),停止当前序列;
    • 如果 (n) 在 ([x, y]) 内,计入结果。
  3. 重复以上过程,直到所有可能的数字 (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):

  1. 基础数字循环:仅需遍历 9 个基础数字;
  2. 完美整数生成:每个基础数字最多生成 (\log_{10}y) 个完美整数。

因此,总体时间复杂度为: [ O(9 \cdot \log_{10}y) ]

在最坏情况下((y = 10^9)),(\log_{10}y \approx 9),计算效率非常高。


总结

本题通过对完美整数的定义和特性的深入分析,设计了一种基于 直接生成 的优化算法,有效避免了大区间遍历的低效操作。通过这种方法,我们能够在极大范围内快速统计出完美整数的数量。这种思路不仅适用于该问题,也为类似问题提供了一种有效的解决模板。