3. Prime List
The problem can be found at the following link: ๐ Question Link
๐งฉ Problem Description
You are given the head of a singly linked list. Your task is to replace the value of each node with the nearest prime number.
If multiple prime numbers are equidistant from the current value, choose the smaller one. Return the head of the updated linked list.
๐ Examples
Example 1:
Input: head = 2 โ 6 โ 10
Output: 2 โ 5 โ 11
Explanation:
2 is already prime.
6 has nearest primes 5 and 7 โ choose 5.
10 has nearest primes 7 and 11 โ choose 11.
Example 2:
Input: head = 1 โ 15 โ 20
Output: 2 โ 13 โ 19
Explanation:
Nearest prime to 1 is 2.
15 โ nearest primes: 13 and 17 โ choose 13.
20 โ nearest primes: 19 and 23 โ choose 19.
๐ Constraints
$1 \leq \text{Number of nodes} \leq 10^4$
$1 \leq \text{Node.val} \leq 10^4$
โ
My Approach
Sieve of Eratosthenes + Two-pointer Prime Search
Core Idea:
Precompute all prime numbers up to twice the maximum value in the list using the Sieve of Eratosthenes. Then, for each node, scan outwards from its value to find the closest prime (checking both left and right directions simultaneously). This guarantees optimal lookup and replacement for large datasets.
Algorithm Steps:
Traverse the list once to find the maximum value
m
.Build a sieve array of size
2*m+1
to mark prime numbers.Traverse the list again:
For each node, search outward from
node.val
until a prime is found (prefer the smaller one if both directions are valid).Replace the value in the node.
Return the updated head.
๐งฎ Time and Auxiliary Space Complexity
Expected Time Complexity: O(n + mยทloglogm), where
n
is the number of nodes andm
is the maximum value. Sieve is built once, and each node is updated in amortized constant time.Expected Auxiliary Space Complexity: O(m), to store the sieve of prime numbers.
๐ง Code (C++)
class Solution {
public:
Node* primeList(Node* h) {
int m = 0;
for (auto p = h; p; p = p->next) m = max(m, p->val);
vector<char> s(2*m+1, 1);
s[0] = s[1] = 0;
for (int i = 2; i*i <= 2*m; ++i)
if (s[i])
for (int j = i*i; j <= 2*m; j += i)
s[j] = 0;
for (auto p = h; p; p = p->next) {
int x = p->val, d = 0;
while (1) {
if (x-d > 1 && s[x-d]) { p->val = x-d; break; }
if (x+d <= 2*m && s[x+d]) { p->val = x+d; break; }
++d;
}
}
return h;
}
};
๐งโ๐ป Code (Java)
class Solution {
Node primeList(Node h) {
int m = 0;
for (Node p = h; p != null; p = p.next) m = Math.max(m, p.val);
boolean[] s = new boolean[2*m+1];
Arrays.fill(s, true);
s[0] = s[1] = false;
for (int i = 2; i*i <= 2*m; i++)
if (s[i])
for (int j = i*i; j <= 2*m; j += i) s[j] = false;
for (Node p = h; p != null; p = p.next) {
int x = p.val, d = 0;
while (true) {
if (x-d > 1 && s[x-d]) { p.val = x-d; break; }
if (x+d <= 2*m && s[x+d]) { p.val = x+d; break; }
d++;
}
}
return h;
}
}
๐ Code (Python)
class Solution:
def primeList(self, h):
m = 0; p = h
while p: m = max(m, p.val); p = p.next
s = [1]*(2*m+1); s[0] = s[1] = 0
for i in range(2, int((2*m)**0.5)+1):
if s[i]: s[i*i:2*m+1:i] = [0]*len(range(i*i, 2*m+1, i))
p = h
while p:
x, d = p.val, 0
while 1:
if x-d > 1 and s[x-d]: p.val = x-d; break
if x+d <= 2*m and s[x+d]: p.val = x+d; break
d += 1
p = p.next
return h
๐ง Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: ๐ฌ Any Questions?. Letโs make this learning journey more collaborative!
โญ If you find this helpful, please give this repository a star! โญ
๐Visitor Count
Last updated