{x}
blog image

Prime Palindrome

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.

  • For example, 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.

  • For example, 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

Solution Explanation for Prime Palindrome

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:

  1. 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.

  2. reverse(x) function: This helper function reverses an integer x. It extracts digits one by one from the right, building the reversed number.

  3. Main logic: The main part of the solution iterates through numbers, starting from n. For each number:

    • It checks if the number is a palindrome using the reverse() function.
    • If it's a palindrome, it checks if it's prime using the isPrime() function.
    • If both conditions are met, the number is returned as the result.
    • If the number is between 10,000,000 and 100,000,000 (inclusive), it jumps directly to 100,000,000 as there are no prime palindromes in that range that we haven't already encountered. This optimization is based on the structure of palindromes.
    • Otherwise, the loop continues to the next number (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.