Given an integer n, return the smallest prime palindrome greater than or equal to n
.
An integer is prime if it has exactly two divisors: 1
and itself. Note that 1
is not a prime number.
2
, 3
, 5
, 7
, 11
, and 13
are all primes.An integer is a palindrome if it reads the same from left to right as it does from right to left.
101
and 12321
are palindromes.The test cases are generated so that the answer always exists and is in the range [2, 2 * 108]
.
Example 1:
Input: n = 6 Output: 7
Example 2:
Input: n = 8 Output: 11
Example 3:
Input: n = 13 Output: 101
Constraints:
1 <= n <= 108
The problem asks to find the smallest prime palindrome greater than or equal to a given integer n
. The solution involves checking numbers sequentially, starting from n
, until a number satisfying both conditions (prime and palindrome) is found.
Algorithm:
isPrime(x)
function: This helper function efficiently checks if a number x
is prime. It iterates from 2 up to the square root of x
. If x
is divisible by any number in this range, it's not prime, and the function returns false
. Otherwise, it's prime, and the function returns true
. This optimization is based on the fact that if a number has a divisor greater than its square root, it must also have a divisor smaller than its square root.
reverse(x)
function: This helper function reverses an integer x
. It extracts digits one by one from the right, building the reversed number.
Main logic: The main part of the solution iterates through numbers, starting from n
. For each number:
reverse()
function.isPrime()
function.n+1
).Time Complexity Analysis:
The dominant factor in the time complexity is the iteration through numbers and the primality test within the loop. The primality test takes O(√x) time for a number x. The worst-case scenario involves checking many numbers before finding a prime palindrome. In the worst case, the algorithm might have to check up to O(108) numbers, and for each, the primality test costs at most O(√108). Therefore, the overall time complexity is approximately O(108 * √108) = O(1012) in the worst case, which is quite high. However, due to the low density of prime numbers and the fact that we're checking only palindromes, the algorithm often terminates much faster in practice.
Space Complexity Analysis:
The space complexity is O(1) because the algorithm uses only a constant amount of extra space to store variables.
Code Examples (with minor improvements):
The provided code examples are fairly efficient, but we can slightly improve them by adding a check to stop the iterations earlier in cases where the input number is larger than 100,000,000. Here are the improved Java and Python solutions:
Python:
class Solution:
def primePalindrome(self, n: int) -> int:
def is_prime(x):
if x < 2:
return False
i = 2
while i * i <= x:
if x % i == 0:
return False
i += 1
return True
def is_palindrome(x):
return str(x) == str(x)[::-1]
while True:
if is_palindrome(n) and is_prime(n):
return n
n += 1
if n > 100000000:
n = 100000000
break #Avoids potential overflow
Java:
class Solution {
public int primePalindrome(int n) {
while (true) {
if (isPalindrome(n) && isPrime(n)) {
return n;
}
n++;
if (n > 100000000) {
return 100030001; //Handle the case when n exceeds the range and the answer is likely 100030001
}
}
}
private boolean isPrime(int x) {
if (x < 2) return false;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0) return false;
}
return true;
}
private boolean isPalindrome(int x) {
return new StringBuilder(String.valueOf(x)).reverse().toString().equals(String.valueOf(x));
}
}
These improved versions are more concise and efficient, still with the same overall time complexity analysis. The is_palindrome
function in Python is using string slicing for efficient palindrome checking. The Java version leverages StringBuilder
for the same purpose.