leetcode
leetcode 2401 ~ 2450
统计对称整数的数目

统计对称整数的数目

难度:

标签:

题目描述

You are given two positive integers low and high.

An integer x consisting of 2 * n digits is symmetric if the sum of the first n digits of x is equal to the sum of the last n digits of x. Numbers with an odd number of digits are never symmetric.

Return the number of symmetric integers in the range [low, high].

 

Example 1:

Input: low = 1, high = 100
Output: 9
Explanation: There are 9 symmetric integers between 1 and 100: 11, 22, 33, 44, 55, 66, 77, 88, and 99.

Example 2:

Input: low = 1200, high = 1230
Output: 4
Explanation: There are 4 symmetric integers between 1200 and 1230: 1203, 1212, 1221, and 1230.

 

Constraints:

  • 1 <= low <= high <= 104

代码结果

运行时间: 48 ms, 内存: 16.4 MB


/*
 * 题目思路:
 * 使用 Java Stream 遍历范围内的每个数字,检查其是否满足对称整数的条件。
 * 过滤出对称整数并计数。
 */
import java.util.stream.IntStream;

public class SymmetricIntegersStream {
    public static int countSymmetricIntegers(int low, int high) {
        return (int) IntStream.rangeClosed(low, high)
                .filter(SymmetricIntegersStream::isSymmetric)
                .count();
    }

    private static boolean isSymmetric(int num) {
        String s = String.valueOf(num);
        int len = s.length();
        if (len % 2 != 0) return false; // 必须是偶数位
        int half = len / 2;
        int sum1 = 0, sum2 = 0;
        for (int i = 0; i < half; i++) {
            sum1 += s.charAt(i) - '0';
            sum2 += s.charAt(i + half) - '0';
        }
        return sum1 == sum2;
    }

    public static void main(String[] args) {
        System.out.println(countSymmetricIntegers(1, 100)); // 输出: 9
        System.out.println(countSymmetricIntegers(1200, 1230)); // 输出: 4
    }
}

解释

方法:

该题解通过预计算所有可能的对称整数并存储在一个列表中。然后,它遍历这个列表,统计在给定的区间 [low, high] 内的对称整数的数量。这个方法避免了对每个数字进行检查,而是直接查找预定义的有效值。

时间复杂度:

O(m) ,其中 m 是预定义对称整数列表的长度。

空间复杂度:

O(m),其中 m 是预定义对称整数列表的长度。

代码细节讲解

🦆
在预计算对称整数时,如何确保所有可能的2 * n位对称整数都被生成并被考虑在内?
在预计算对称整数的过程中,可以使用递归或循环来生成所有可能的对称数。具体方法是,从一个基础数字(如1位或2位的数字)开始,逐步在其两边附加相同的数字,形成更长的对称数。例如,从1开始生成11, 111, 1111等。同样,应考虑从0开始的数字(如00, 000, 0000等),尽管要注意,以0开头的数字可能不合适作为整数使用。整个生成过程需要保证覆盖所有位数的组合,直到达到所需的位数上限。
🦆
题解中提到的列表`fac`是否包含了所有小于10000的对称整数?如果没有,如何处理那些非列出的对称整数?
题解中的列表`fac`可能并不包含所有小于10000的对称整数,例如单个数字1-9以及如101, 202这样的数字可能未被包括。为处理未列出的对称整数,可以在初始化阶段将所有对称整数计算并存储,确保列表完整。如果列表不完整,可以通过动态生成对称数来补充,或在算法初始阶段进行完整的对称数生成,再进行范围过滤。
🦆
对于比较数字是否位于`low`和`high`之间,为什么选择使用遍历列表而不是其他搜索技术,比如二分查找?
遍历列表是一种简单的方法,适用于列表项数不多时。对于二分查找,这种方法更适合在有序列表中快速定位和检查范围,可以提高效率。在本题中,如果`fac`列表是有序的,并且列表项数相对较大,使用二分查找来确定`low`和`high`在列表中的位置,然后计算这两点之间的对称整数数目,将更加高效。
🦆
如果`low`和`high`的数值非常接近而对称整数列表`fac`很大,这种方法的效率如何?是否有更优化的方法来处理这种情况?
如果`low`和`high`非常接近而列表很大,遍历整个列表会不够高效,因为大多数数字都不在感兴趣的范围内。在这种情况下,使用二分查找定位`low`和`high`的位置能显著减少不必要的比较,直接定位到感兴趣的区间,从而提高效率。此外,如果对称整数的数量相对于范围较小,可以考虑直接生成指定范围内的对称整数,而无需预先生成大量可能不被使用的数据。

相关问题