LC-2523.范围内最接近的两个质数

题目描述

leetcode 困难题

给你两个正整数 left 和 right ,请你找到两个整数 num1 和 num2 ,它们满足:

left <= nums1 < nums2 <= right  。
nums1 和 nums2 都是 质数 。
nums2 - nums1 是满足上述条件的质数对中的 最小值 。
请你返回正整数数组 ans = [nums1, nums2] 。如果有多个整数对满足上述条件,请你返回 nums1 最小的质数对。如果不存在符合题意的质数对,请你返回 [-1, -1] 。

如果一个整数大于 1 ,且只能被 1 和它自己整除,那么它是一个质数。

示例1:

1
2
3
4
5
输入:left = 10, right = 19
输出:[11,13]
解释:10 到 19 之间的质数为 11 ,13 ,17 和 19
质数对的最小差值是 2 ,[11,13] 和 [17,19] 都可以得到最小差值。
由于 11 17 小,我们返回第一个质数对。

提示1:

1
1 <= left <= right <= 106

埃氏筛

参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
static boolean[] isPrime = new boolean[1000001];
static{
for(int i = 2; i < isPrime.length; i++){
isPrime[i] = true;
}
for(int i = 2; i * i < isPrime.length; i++){
if(!isPrime[i]){
continue;
}
for(long j = 1L * i * i; j < isPrime.length; j += i){
isPrime[(int)j] = false;
}
}
}

public int[] closestPrimes(int left, int right) {
int[] ans = {-1, -1};
int pre = -1;
for(int i = left; i <= right; i++){
if(!isPrime[i]){
continue;
}
if(pre == -1){
pre = i;
continue;
}
if(ans[0] == -1){
ans[0] = pre;
ans[1] = i;
pre = i;
continue;
}
if(i - pre < ans[1] - ans[0]){
ans[0] = pre;
ans[1] = i;
}
pre = i;
}
return ans;
}
}

线性筛(欧拉筛)

参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Solution {
static int[] prime = new int[1000001];
static boolean[] visit = new boolean[1000001];
static int cnt = 0;
static{
for(int i = 2; i < visit.length; i++){
if(!visit[i]){
prime[cnt++] = i;
}
for(int j = 0; j < cnt; j++){
if(1l * i * prime[j] >= visit.length){
break;
}
visit[i * prime[j]] = true;
if(i % prime[j] == 0){
break;
}
}
}
cnt--;
}

public int[] closestPrimes(int left, int right) {
int p = -1, q = - 1;
for(int i = leftBound(left); i < cnt; i++){
if(prime[i + 1] > right){
break;
}
if(p == -1 || prime[i + 1] - prime[i] < q - p){
p = prime[i];
q = prime[i + 1];
}
}
return new int[]{p, q};
}

private int leftBound(int target){
int left = 0, right = cnt + 1;
while(left < right){
int mid = left + (right - left >> 1);
if(prime[mid] < target){
left = mid + 1;
}else{
right = mid;
}
}
return left;
}
}

LC-2523.范围内最接近的两个质数
https://wecgwm.github.io/2023/03/01/LC-2523-范围内最接近的两个质数/
作者
yichen
发布于
2023年3月1日
许可协议