你需要找到由两个 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}