> 文章列表 > Leetcode.2523 范围内最接近的两个质数

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

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

题目链接

Leetcode.2523 范围内最接近的两个质数 Rating : 1650

题目描述

给你两个正整数 leftright请你找到两个整数 num1num2 ,它们满足:

  • left<=nums1<nums2<=rightleft <= nums1 < nums2 <= rightleft<=nums1<nums2<=right
  • nums1nums2 都是 质数
  • nums2−nums1nums2 - nums1nums2nums1 是满足上述条件的质数对中的 最小

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

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

示例 1:

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

示例 2:

输入:left = 4, right = 6
输出:[-1,-1]
解释:给定范围内只有一个质数,所以题目条件无法被满足。

提示:

  • 1<=left<=right<=1061 <= left <= right <= 10^61<=left<=right<=106

解法:欧拉筛 + 二分

欧拉筛(线性筛)

先通过 欧拉筛 预处理 10610^6106 内的质数,将其存入 primesprimesprimes 中。

再通过 二分 找到第一个大于等于 lll 的下标 iii,从 iii 开始找寻最小质数对(primes[i]primes[i]primes[i] 同样也应该 ≤r\\leq rr)。

时间复杂度: O(n)O(n)O(n)

C++代码:

const int N = 1e6;
vector<int> primes;
// 预处理 1e6 范围内的质数,将其存入 primes 中 
int get_prime = [](){bool st[N + 1]={};for(int i = 2;i <= N;i++){if(!st[i]) primes.push_back(i);for(auto p:primes){if(i * p > N) break;st[i * p] = true;if(i % p == 0) break;}}return 0;
}();class Solution {
public:vector<int> closestPrimes(int l, int r) {//找到第一个大于等于 l 的下标 iauto i = lower_bound(primes.begin(),primes.end(),l) - primes.begin();int n = primes.size();int a = -1 , b = -1;int d = 1e9;//从 i 开始寻找最小质数对 ,i 和 i + 1是一对,前提是 primes[i+1] <= rfor(;i + 1 < n && primes[i+1] <= r;i++){if(primes[i+1] - primes[i] < d){d = primes[i+1] - primes[i];a = primes[i] , b = primes[i+1]; }}return {a,b};}
};