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

题目链接

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

题目描述

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

  • l e f t < = n u m s 1 < n u m s 2 < = r i g h t left <= nums1 < nums2 <= right left<=nums1<nums2<=right
  • nums1nums2 都是 质数
  • n u m s 2 − n u m s 1 nums2 - nums1 nums2nums1 是满足上述条件的质数对中的 最小值

请你返回正整数数组 a n s = [ n u m s 1 , n u m s 2 ] 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 < = l e f t < = r i g h t < = 1 0 6 1 <= left <= right <= 10^6 1<=left<=right<=106

解法:欧拉筛 + 二分

欧拉筛(线性筛)

先通过 欧拉筛 预处理 1 0 6 10^6 106 内的质数,将其存入 p r i m e s primes primes 中。

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

时间复杂度: 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 的下标 i
        auto 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] <= r
        for(;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};
    }
};

你可能感兴趣的:(Leetcode,leetcode,算法,欧拉筛)