题目

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

示例 1:

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

示例 2:

输入: n = 1
输出: 9

提示:

1 <= n <= 8

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/largest-palindrome-product
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

从大值开始枚举回文数,判断是否可以拆成两个n位数乘积。

比如,n=2,最大的两位数为99,从99开始构造回文数,左边为99时右边也是99,回文为9999,不过其大于479. 最大回文数乘积 - 图1,因此跳过。继续看98,回文数为9889,也大于479. 最大回文数乘积 - 图2,跳过。再看97,9779不超过479. 最大回文数乘积 - 图3,但是无法表示为两个两位数乘积,继续看96,95,…,直至找到一个可以拆成两个n位数的回文数。

代码

  1. class Solution {
  2. public int largestPalindrome(int n) {
  3. // n为1时,不适用下面的算法,单独返回
  4. if (n == 1) {
  5. return 9;
  6. }
  7. int k = (int) Math.pow(10, n) - 1;
  8. // 枚举回文左半部分,对应代码中的i
  9. for (int i = k; i >= 1; i--) {
  10. long pal = i;
  11. int tmp = i;
  12. while (tmp > 0) {
  13. pal = pal * 10 + tmp % 10;
  14. tmp /= 10;
  15. }
  16. // 回文数不可以超过k的平方
  17. if (pal > (long) k * k) {
  18. continue;
  19. }
  20. // 判断pal是否可以拆成两个n位数乘积,因子从k开始,另一个因子一定小于k
  21. for (long j = k; j * j >= pal; j--) {
  22. if (pal % j == 0) {
  23. return (int) (pal % 1337);
  24. }
  25. }
  26. }
  27. return -1;
  28. }
  29. }