Given a number n, determine whether it can be expressed as a + b, where both a and b are prime numbers. If such a pair exists, return the pair (a, b) such that a ≤ b. If multiple pairs are possible, return the pair with the smallest value of a. If no such pair exists, return [-1, -1].
Examples:
Input: n = 10
Output: [3 7]
Explanation: There are two possibilities 3, 7 & 5, 5 are both prime & their sum is 10, but we'll pick 3, 7 as 3 < 5.Input: n = 3
Output: [-1 -1]
Explanation: There are no solutions to the number 3.
Table of Content
[Naive Approach] Check Every Possible Pair - O(n√n) Time and O(1) Space
The idea is to try every possible first number a from 2 to n / 2. For each value, check whether both a and n - a are prime. Since we start from the smallest value of a, the first valid pair obtained is the required answer.
Working of Approach:
- Iterate through all possible values of a from 2 to n / 2.
- For each a, check if both a and n - a are prime using a simple primality test.
- If both numbers are prime, return {a, n - a} immediately.
- If no valid pair is found, return {-1, -1}.
#include <iostream>
#include <vector>
using namespace std;
// Function to check whether a number is prime
bool isPrime(int x)
{
if (x < 2)
return false;
for (int i = 2; i * i <= x; i++)
{
if (x % i == 0)
return false;
}
return true;
}
// Function to find two prime numbers whose sum is n
vector<int> getPrimes(int n)
{
// Try every possible first prime
for (int a = 2; a <= n / 2; a++)
{
// If both numbers are prime, return the pair
if (isPrime(a) && isPrime(n - a))
return {a, n - a};
}
// No valid pair exists
return {-1, -1};
}
int main()
{
int n = 10;
vector<int> ans = getPrimes(n);
cout << "[" << ans[0] << " " << ans[1] << "]";
return 0;
}
import java.util.*;
// Function to check whether a number is prime
public class GFG {
static 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;
}
// Function to find two prime numbers whose sum is n
static ArrayList<Integer> getPrimes(int n)
{
// Try every possible first prime
for (int a = 2; a <= n / 2; a++) {
// If both numbers are prime, return the pair
if (isPrime(a) && isPrime(n - a)) {
ArrayList<Integer> ans = new ArrayList<>();
ans.add(a);
ans.add(n - a);
return ans;
}
}
// No valid pair exists
ArrayList<Integer> ans = new ArrayList<>();
ans.add(-1);
ans.add(-1);
return ans;
}
public static void main(String[] args)
{
int n = 10;
ArrayList<Integer> ans = getPrimes(n);
System.out.println("[" + ans.get(0) + " "
+ ans.get(1) + "]");
}
}
# Function to check whether a number is prime
def isPrime(x):
if x < 2:
return False
for i in range(2, int(x**0.5) + 1):
if x % i == 0:
return False
return True
# Function to find two prime numbers whose sum is n
def getPrimes(n):
# Try every possible first prime
for a in range(2, n // 2 + 1):
# If both numbers are prime, return the pair
if isPrime(a) and isPrime(n - a):
return [a, n - a]
# No valid pair exists
return [-1, -1]
if __name__ == '__main__':
n = 10
ans = getPrimes(n)
print(ans)
using System;
using System.Collections.Generic;
class GFG {
// Function to check whether a number is prime
static bool IsPrime(int x)
{
if (x < 2)
return false;
for (int i = 2; i * i <= x; i++) {
if (x % i == 0)
return false;
}
return true;
}
// Function to find two prime numbers whose sum is n
static List<int> getPrimes(int n)
{
// Try every possible first prime
for (int a = 2; a <= n / 2; a++) {
// If both numbers are prime, return the pair
if (IsPrime(a) && IsPrime(n - a))
return new List<int>{ a, n - a };
}
// No valid pair exists
return new List<int>{ -1, -1 };
}
// Driver code
static void Main()
{
int n = 10;
List<int> ans = getPrimes(n);
Console.WriteLine("[" + ans[0] + " " + ans[1]
+ "]");
}
}
// Function to check whether a number is prime
function isPrime(x)
{
if (x < 2)
return false;
for (let i = 2; i * i <= x; i++) {
if (x % i === 0)
return false;
}
return true;
}
// Function to find two prime numbers whose sum is n
function getPrimes(n)
{
// Try every possible first prime
for (let a = 2; a <= n / 2; a++) {
// If both numbers are prime, return the pair
if (isPrime(a) && isPrime(n - a))
return [ a, n - a ];
}
// No valid pair exists
return [ -1, -1 ];
}
// Driver Code
const n = 10;
const ans = getPrimes(n);
console.log(ans);
Output
[3 7]
[Expected Approach] Using Sieve of Eratosthenes (Prime Pair for Given Sum) - O(n log log n) Time and O(n) Space
We use the Sieve of Eratosthenes to precompute all prime numbers up to n. Then we check pairs (i, n - i) to find two prime numbers whose sum is n. The first such pair found will be the answer.
Working of Approach:
- Generate all primes up to
nusing Sieve - Store results in
isPrime[] - Traverse from
i = 2ton/2 - For each
i, check IfisPrime[i]andisPrime[n - i], then return the pair{i, n - i} - If no valid pair is found, return {-1, -1}.
Let us understand with an example:
- For n = 10, first generate all prime numbers up to 10 using the Sieve of Eratosthenes. The primes are {2, 3, 5, 7}.
- Start checking possible first numbers from 2 to 10 / 2 = 5.
- For i = 2, 10 - 2 = 8, but 8 is not prime, so continue.
- For i = 3, 10 - 3 = 7, and both 3 and 7 are prime.
- Return the pair [3, 7] immediately since it has the smallest possible first element.
#include <iostream>
#include <vector>
using namespace std;
// Function to generate primes up to n
// using Sieve of Eratosthenes
vector<bool> sieve(int n)
{
// Initialize all as prime
vector<bool> isPrime(n + 1, true);
// 0 and 1 are not primes
isPrime[0] = isPrime[1] = false;
// Mark non-primes using multiples of each prime
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;
}
// Function to find two primes whose sum equals n
vector<int> getPrimes(int n)
{
// Get all primes up to n
vector<bool> isPrime = sieve(n);
// Iterate to find the smallest pair
for (int i = 2; i <= n / 2; i++)
{
if (isPrime[i] && isPrime[n - i])
{
return {i, n - i};
}
}
// Return empty if no pair found (won't occur)
return {-1, -1};
}
int main()
{
int n = 10;
vector<int> ans = getPrimes(n);
cout << "[" << ans[0] << " " << ans[1] << "]";
return 0;
}
import java.util.*;
public class GFG {
// Function to generate primes up to n
// using Sieve of Eratosthenes
static boolean[] sieve(int n)
{
// Initialize all as prime
boolean[] isPrime = new boolean[n + 1];
Arrays.fill(isPrime, true);
// 0 and 1 are not primes
isPrime[0] = false;
isPrime[1] = false;
// Mark non-primes using multiples of each prime
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;
}
// Function to find two primes whose sum equals n
static ArrayList<Integer> getPrimes(int n)
{
// Get all primes up to n
boolean[] isPrime = sieve(n);
// Iterate to find the smallest pair
for (int i = 2; i <= n / 2; i++) {
if (isPrime[i] && isPrime[n - i]) {
ArrayList<Integer> ans = new ArrayList<>();
ans.add(i);
ans.add(n - i);
return ans;
}
}
ArrayList<Integer> ans = new ArrayList<>();
ans.add(-1);
ans.add(-1);
return ans;
}
public static void main(String[] args)
{
int n = 10;
ArrayList<Integer> ans = getPrimes(n);
System.out.println("[" + ans.get(0) + " "
+ ans.get(1) + "]");
}
}
# Function to generate primes up to n
# using Sieve of Eratosthenes
def sieve(n):
# Initialize all as prime
isPrime = [True] * (n + 1)
# 0 and 1 are not primes
isPrime[0] = isPrime[1] = False
# Mark non-primes using multiples of each prime
for i in range(2, int(n**0.5) + 1):
if isPrime[i]:
for j in range(i * i, n + 1, i):
isPrime[j] = False
return isPrime
# Function to find two primes whose sum equals n
def getPrimes(n):
# Get all primes up to n
isPrime = sieve(n)
# Iterate to find the smallest pair
for i in range(2, n // 2 + 1):
if isPrime[i] and isPrime[n - i]:
return [i, n - i]
# Return empty if no pair found (won't occur)
return [-1, -1]
if __name__ == "__main__":
n = 10
ans = getPrimes(n)
print(f"[{ans[0]} {ans[1]}]")
using System;
using System.Collections.Generic;
class GFG {
// Function to generate primes up to n
// using Sieve of Eratosthenes
static bool[] Sieve(int n)
{
// Initialize all as prime
bool[] isPrime = new bool[n + 1];
Array.Fill(isPrime, true);
// 0 and 1 are not primes
isPrime[0] = false;
isPrime[1] = false;
// Mark non-primes using multiples of each prime
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;
}
// Function to find two primes whose sum equals n
static List<int> getPrimes(int n)
{
// Get all primes up to n
bool[] isPrime = Sieve(n);
// Iterate to find the smallest pair
for (int i = 2; i <= n / 2; i++) {
if (isPrime[i] && isPrime[n - i]) {
return new List<int>{ i, n - i };
}
}
return new List<int>{ -1, -1 };
}
static void Main()
{
int n = 10;
List<int> ans = getPrimes(n);
Console.WriteLine("[" + ans[0] + " " + ans[1]
+ "]");
}
}
// Function to generate primes up to n
// using Sieve of Eratosthenes
function sieve(n)
{
// Initialize all as prime
const isPrime = Array(n + 1).fill(true);
// 0 and 1 are not primes
isPrime[0] = isPrime[1] = false;
// Mark non-primes using multiples of each prime
for (let i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (let j = i * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}
return isPrime;
}
// Function to find two primes whose sum equals n
function getPrimes(n)
{
// Get all primes up to n
const isPrime = sieve(n);
// Iterate to find the smallest pair
for (let i = 2; i <= n / 2; i++) {
if (isPrime[i] && isPrime[n - i]) {
return [ i, n - i ];
}
}
// Return empty if no pair found (won't occur)
return [ -1, -1 ];
}
// Driver Code
const n = 10;
const ans = getPrimes(n);
console.log(`[${ans[0]} ${ans[1]}]`);
Output
[3 7]
Note: Another approach to solve this problem is based on Goldbach's conjecture, which states that every even integer greater than 2 can be expressed as the sum of two prime numbers.