Problem
Given an even number (greater than 2), return two prime numbers whose sum will be equal to the given number. A solution will always exist as per Goldbach’s conjecture. If there are multiple solutions possible, return the lexicographically smaller solution. If [a, b]
is one solution with a <= b
, and [c, d]
is another solution with c <= d
, then [a, b] < [c, d]
if and only if a < c
or a == c
and b < d
.
Examples
Examle 1
Input: 4
Output: 2 + 2 = 4
Explanation: The only pair of prime numbers that sum up to 4 is (2, 2).
Examle 2
Input: 10
Output: 3 + 7 = 10
Explanation: The valid pairs are (3, 7) and (5, 5). According to lexicographical order (3, 7) < (5, 5). Hence, the output is 3 + 7 = 10.
Solution
Method 1 - Using Goldbach’s conjecture and Sieve of Eratosthenes
The approach is based on Goldbach’s conjecture that every even number greater than 2 can be expressed as the sum of two prime numbers. We’ll generate all prime numbers up to the given number using the Sieve of Eratosthenes technique and check pairs of these primes to find the required pair that sums up to the given number.
Here is the approach:
- Generate Prime Numbers: Use the Sieve of Eratosthenes to generate a list of prime numbers up to the given number.
- Find Prime Pair: Iterate over the list of prime numbers and for each prime
p
, check ifnumber - p
is also a prime. - Return Lexicographically Smallest Pair: Ensure the pair
[a, b]
such thata <= b
is the lexicographically smallest pair found.
Code
Java
public class Solution {
public int[] findPrimePairSum(int n) {
boolean[] isPrime = sieveOfEratosthenes(n);
for (int i = 2; i <= n / 2; i++) {
if (isPrime[i] && isPrime[n - i]) {
return new int[]{i, n - i};
}
}
return new int[0]; // just a fallback, per problem statement this won't happen
}
private boolean[] sieveOfEratosthenes(int n) {
boolean[] isPrime = new boolean[n + 1];
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}
return isPrime;
}
public static void main(String[] args) {
Solution solution = new Solution();
int n = 10;
int[] result = solution.findPrimePairSum(n);
System.out.println(result[0] + " + " + result[1] + " = " + n);
}
}
Python
class Solution:
def findPrimePairSum(self, n: int):
is_prime = self.sieve_of_eratosthenes(n)
for i in range(2, n // 2 + 1):
if is_prime[i] and is_prime[n - i]:
return i, n - i
return None
def sieve_of_eratosthenes(self, n: int):
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
p = 2
while p * p <= n:
if is_prime[p]:
for i in range(p * p, n + 1, p):
is_prime[i] = False
p += 1
return is_prime
# Example usage
solution = Solution()
n = 10
result = solution.findPrimePairSum(n)
print(f"{result[0]} + {result[1]} = {n}")
Complexity
- ⏰ Time complexity:
O(n log log n)
- Generating prime numbers using the Sieve of Eratosthenes takes
O(n log log n)
. - Checking pairs takes up to
O(n/2)
, which isO(n)
in the worst case.
- Generating prime numbers using the Sieve of Eratosthenes takes
- 🧺 Space complexity:
O(n)
for storing the boolean array which indicates primality.