leetcode
leetcode 401 ~ 450
最大回文数乘积

最大回文数乘积

难度:

标签:

题目描述

给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大,所以返回它对 1337 取余

 

示例 1:

输入:n = 2
输出:987
解释:99 x 91 = 9009, 9009 % 1337 = 987

示例 2:

输入: n = 1
输出: 9

 

提示:

  • 1 <= n <= 8

代码结果

运行时间: 27 ms, 内存: 15.9 MB


// Problem Statement: Find the largest palindrome made from the product of two n-digit numbers. Return the result modulo 1337.
// 
// Approach with Java Streams:
// 1. Use streams to generate numbers and filter the pairs.
// 2. For each pair, calculate the product and check for palindrome.
// 3. Find the maximum palindrome and return the result modulo 1337.
 
import java.util.stream.IntStream;
 
public class Solution {
    public int largestPalindrome(int n) {
        if (n == 1) return 9;
        int upperLimit = (int) Math.pow(10, n) - 1;
        int lowerLimit = (int) Math.pow(10, n - 1);
        int maxPalindrome = IntStream.rangeClosed(lowerLimit, upperLimit).boxed()
            .flatMap(i -> IntStream.rangeClosed(lowerLimit, i).mapToObj(j -> i * j))
            .filter(Solution::isPalindrome)
            .max(Integer::compare)
            .orElse(0);
        return maxPalindrome % 1337;
    }
 
    private static boolean isPalindrome(int num) {
        int original = num;
        int reversed = 0;
        while (num > 0) {
            reversed = reversed * 10 + num % 10;
            num /= 10;
        }
        return original == reversed;
    }
}

解释

方法:

该题解采用了一个从高到低构造回文数的方法。首先,对于n位数字,最大可能的数字是10^n-1。解题思路是从这个最大数开始,逐步减小,构造可能的回文数,检查它是否可以由两个n位数的乘积构成。具体做法是,对于每一个数part,将其转换为字符串,并将字符串反转后拼接到原字符串后面,形成一个回文数。然后,从sqrt(cur)开始向下检查,直到10^n,看这个回文数是否能被这些数整除,如果能,则返回该回文数对1337取余的结果。如果在所有n位数范围内找不到符合条件的回文数,最后返回9(即1位数的最大回文数,特殊情况处理)。

时间复杂度:

O(10^n * sqrt(10^n))

空间复杂度:

O(1)

代码细节讲解

🦆
题解中提到的方法是从最大可能的数字开始逐步减小,但是为什么选择从`10^n-1`开始而不是直接从`10^n`开始?
在给定一个n位数的定义中,n位数的范围是从`10^(n-1)`到`10^n-1`。例如,如果n=2,那么两位数的范围是从10到99。因此,`10^n`实际上是一个(n+1)位的数字,而不是n位。所以,使用`10^n-1`作为起始点,因为它是n位数字中的最大值。
🦆
在检查一个数是否可以被n位数整除时,为什么是从`sqrt(cur)`开始而不是从`10^n-1`开始向下检查?
检查一个数是否可以被另一个数整除,如果我们已知这个数是两个n位数字的乘积构成的回文数,最大的乘数不会超过这个回文数的平方根。这是因为,如果存在两个乘数a和b使得a*b等于这个回文数,并且a和b都大于`sqrt(cur)`,那么a*b会超过cur,这与我们的假设矛盾。因此,从`sqrt(cur)`开始向下检查到`10^(n-1)`(n位数的最小值)是足够的,这样可以节省计算时间和资源。
🦆
题解中提到,如果在所有n位数范围内找不到符合条件的回文数,则返回9。这种情况是否真的可能发生,尤其是对于n大于1的情况?
实际上,对于n大于1的情况,总是可以找到至少一个回文数,它是两个n位数的乘积。这是因为回文数的生成和检查涵盖了所有从`10^n-1`到`10^(n-1)`的数,这保证了我们检查了所有可能的回文数。返回9的情况主要是针对n=1的特殊情况,这是因为1位数字的最大回文数是9。对于n大于1的情况,这种情况不太可能发生,因为会有更大的回文数存在。

相关问题