回文素数
题目来源
leetcode 886 回文素数
题目描述
求出大于或等于 N 的最小回文素数。
回顾一下,如果一个数大于 1,且其因数只有 1 和它自身,那么这个数是素数。
例如,2,3,5,7,11 以及 13 是素数。
回顾一下,如果一个数从左往右读与从右往左读是一样的,那么这个数是回文数。
例如,12321 是回文数。
解题过程与思路
思路一: 暴力枚举从n开始的每一个数,判断是否回文,是否是素数,意料之中超时了。
class Solution {
public int primePalindrome(int n) {
for(int i=n;i<=(int)(2*1e8);i++)
{
if(isHui(i)&&isPrime(i))
return i;
}
return 0;
}
public boolean isHui(int n)
{
String str1=String.valueOf(n);
StringBuilder str2=new StringBuilder(str1);
str2.reverse();
for (int i = 0; i < str1.length(); i++) {
if (str1.charAt(i) != str2.charAt(i)) {
return false;
}
}
return true;
}
public boolean isPrime(int n){
if(n==1)
return false;
int i=2;
for(;i<n;i++){
if(n%i==0)
return false;
}
return true;
}
}
思路二:由于两个回文数之间有一个较大的“距离”,我们可以通过先找到下一个回文数,来降低判断的次数,从而降低时间复杂度。
寻找下一个回文数的思路与代码参考了下一个回文数的思路与代码。
怎么找>=N的回文数呢?
先根据N制造出一个回文数:即翻转N的前半段,比如5432 -> 5445,54321 -> 54345。
如果这个数>=N,那就ok了,返回。
但这个数有可能小于N,比如23456 -> 23432,这时23432 < 23456。
这个时候把N的前半段数+1,比如23456前半段是234,加1变成235,再翻转制造回文数->23532,这时就大于23456了
AC代码
class Solution {
public int primePalindrome(int n) {
int ans=n;
while(true)
{
ans=getNextPalindrome(ans);
if(isprime(ans))
return ans;
else
ans++;
}
}
public boolean isprime(int n)
{
if(n==1)
return false;
for(int i=2;i<=Math.sqrt(n);i++)
{
if(n%i==0)
return false;
}
return true;
}
private int getNextPalindrome(int n) {
char[] s = String.valueOf(n).toCharArray();
int mid = s.length/2;
while (true) {
// 制造回文数:把前半段翻转一下复制到后半段
for (int i = 0; i < mid; i++) {
s[s.length -1 - i] = s[i];
}
// 判断制造出来的数是否>=n
int tmp = Integer.valueOf(String.valueOf(s));
if (tmp >= n) return tmp; // 如果>=n,返回这个造出来的数
// 如果比n小,那前半段+1
else {
int j = s.length % 2 == 1? mid: mid-1; // 如果是奇数长度,最靠近中轴的是s[mid];如果是偶数长度,最靠近中轴的是s[mid-1]
// 有9要进位(不用考虑999xxx这样首位要进位的,因为999999这个回文数肯定>=所有999xxx形式的n)
while (s[j] == '9'){
s[j--] = '0';
}
s[j]++;
}
}
}
}