你需要找到由两个 n 位数的乘积组成的最大回文数。

由于结果会很大,你只需返回最大回文数 mod 1337得到的结果。

示例:

输入: 2

输出: 987

解释: 99 x 91 = 9009, 9009 % 1337 = 987

说明:

n 的取值范围为 [1,8]。

答案:

 1public int largestPalindrome(int n) {
 2    long max = (long) Math.pow(10, n) - 1;
 3    long min = max / 10;
 4    for (long h = max; h > min; h--) {
 5        long left = h, right = 0;
 6        for (long i = h; i != 0; right = right * 10 + i % 10, i /= 10, left *= 10) ;
 7        long palindrom = left + right;
 8        for (long i = max; i > min; i--) {
 9            long j = palindrom / i;
10            if (j > i)
11                break;
12            if (palindrom % i == 0)
13                return (int) (palindrom % 1337);
14        }
15    }
16    return 9;
17}

解析:

max表示的是最大的n位数,min表示的是最小的n位数,首先要构造回文数palindrom,然后再判断这个回文数是否能被min到max之间的任何一个数整除,如果能,说明可以有两个n位数相乘得到,直接返回对1337的求余即可。再来看一种解法

 1public int largestPalindrome(int n) {
 2    if (n == 1) return 9;
 3    int max = (int) Math.pow(10, n) - 1;
 4    for (int v = max - 1; v > max / 10; v--) {
 5        long u = Long.valueOf(v + new StringBuilder().append(v).reverse().toString());
 6        for (long x = max; x * x >= u; x--)
 7            if (u % x == 0)
 8                return (int) (u % 1337);
 9    }
10    return 0;
11}

上面这两种解法类似,只不过这种可能更容易理解一些。因为n最大等于8,所以还有一种先找出最大的回文乘积,再进行计算,看下代码,这个不能算是一种解题方式,因为如果这样做的话,算法也就失去的他的意义了。

1public int largestPalindrome(int n) {
2    int[] x = {9, 99, 993, 9999, 99979, 999999, 9998017, 99999999};
3    int[] y = {1, 91, 913, 9901, 99681, 999001, 9997647, 99990001};
4    return ((x[n - 1] % 1337) * (y[n - 1] % 1337)) % 1337;
5}

下面再来看一下最后一种罪魔性的算法

1public int largestPalindrome(int n) {
2    return (-14535 * (n % 2) + 8730 * (n % 3) + 3780 * (n % 4) -
3            426 * (n % 5) - 2180 * (n % 6) + 1500 * (n % 7) +
4            3285 * (n % 8) + 116 * (n % 9)) / 30;
5}