我们看到这个题,看到10的18次方这个规模,远远大于10的8次方,所以不可能一个一个便利,我们可以先把右边界开方,随后得到的数再平方进行判断是否越界,即可将问题规模缩小到10的9次方,让后我们可以进行取一半的策略,即将种子从1开始便利,(1) 1 11 (2) 2 22 (9)9 99 (10)101 1001,每一次循环后判断奇数是否越界,越界后返回cnt就是答案,具体实现如下
public int superpalindromesInRange(String left, String right) {
long l = Long.valueOf(left);//左边界
long r = Long.valueOf(right);//右边界
long limit = (long) Math.sqrt((double) r);//右边界开方
int cnt = 0;//超级回文数
long seed = 1;//种子,可以从1开始便利
long enlarge = 0;//得到的回文数
do {
enlarge = enlarge2(seed);//偶数回文数
if (isVaild(enlarge * enlarge,l,r)) cnt++;//看看平方后是否是回文数,且是否越界
enlarge = enlarge1(seed);//奇数回文数
if (isVaild(enlarge * enlarge,l,r)) cnt++;//同理
seed++;//种子加一
} while (enlarge < limit);//当奇数回文数满足条件,就继续进行
return cnt;
}
static boolean isVaild(long ans, long l, long r){
return isPalindrome(ans) && ans>=l && ans <=r;//判断是否越界
}
static boolean isPalindrome(long n){//判断是否回文
String s = "" + n;
int l = 0;
int r = s.length()-1;
while (l < r){
char ch1 = s.charAt(l);
char ch2 = s.charAt(r);
if (ch1 != ch2) return false;
l++;
r--;
}
return true;
}
static long enlarge1(long seed){//凑出奇数回文数
long ans = seed;
seed/=10;
while (seed!=0){
ans = ans * 10 + seed % 10;
seed/=10;
}
return ans;
}
static long enlarge2(long seed){//凑出偶数回文数
long ans = seed;
while (seed != 0){
ans = ans * 10 + seed % 10;
seed/=10;
}
return ans;
}