题意:
        给定正整数数组A和一个正整数X,设A的长度为N,数组中的元素依次为A[0]~A[N - 1]。
        现要挑选出符合以下条件的所有整数对(l, r):
                   存在至少X个不同的质数,每个质数都可以整除A[l]~A[r]之间的每一个数(A[l], A[l + 1], A[l + 2], ... A[r])。
         现在定义一个整数对(l, r)的长度为r - l + 1,找出长度第K大的整数对长度是多少。
         如果符合条件的数对不足K个,那么返回-1。

方法一:
暴力模拟

思路:
        先打表,获取素数表。
        再用两重循环,得到一个区间;
        并在这个区间里去遍历满足条件的素数,并统计素数的数量;
        如果该区间内素数的数量满足,则将该区间的长度存储到长度数组;
        最后从大到小排序,返回第K大的长度。
        

        
class Solution {
public:
    static const int N=1e7+5;
    bool isPrime[N];//判断是否为素数
    vector<int> prime;//存储素数
    int GetKthLength(vector<int>& A, int X, int K) {
        int n=A.size();
        getPrime();//获取素数表
        vector<int> res;
        for(int i=0;i<n;i++){//遍历每个区间
            for(int j=i;j<n;j++){
                if(judge(i,j,A,X)){//如果满足,将区间长度加入队列
                    res.push_back(j-i+1);
                }
            }
        }
        sort(res.begin(),res.end(),greater<int>());//将区间长度从大到小排序
        return res.size()<K?-1:res[K-1];//选择第K大长度
    }
    
    int judge(int l,int r,vector<int> A,int num){

        int ma=0;//取[l,r]的最大值
        for(int i=l;i<=r;i++)
            ma=max(ma,A[i]);
        for(int i=0;prime[i]<=ma;i++){//遍历素数表,判断该素数是否可行
            int flag=0;
            for(int j=l;j<=r;j++){
                if(A[j]%prime[i]!=0){//不能整除,则这个素数不满足,舍弃
                    flag=1;
                    break;
                }
            }
            if(flag==0)
                num--;
            if(num==0)
                return 1;
        }
        return 0;
    }
    
    void getPrime(){//线性筛素数O(n)
        int num=0;//素数的个数
        memset(isPrime,true,sizeof(isPrime));
        for(int i=2;i<=N;i++){
            if(isPrime[i]){
                prime.push_back(i);
                num++;
            }
            for(int j=0;j<num&&i*prime[j]<=N;j++){
                isPrime[i*prime[j]]=false;
                if(i%prime[j]==0)
                    break;
            }
        }
    }
    
};
时间复杂度:
空间复杂度:

方法二:
优化

思路:
        对于一个区间的数值,要求区间的每个数都要整除一个素数。
        那么我们可以获取这个区间的最小值,
      以最小值作为临界点,是素数小于等于最小值。
        这样可以优化遍历素数的个数。

class Solution {
public:
    static const int N=1e7+5;
    bool isPrime[N];//判断是否为素数
    vector<int> prime;//存储素数
    int GetKthLength(vector<int>& A, int X, int K) {
        int n=A.size();
        getPrime();//获取素数表
        vector<int> res;
        for(int i=0;i<n;i++){//遍历每个区间
            for(int j=i;j<n;j++){
                if(judge(i,j,A,X)){//如果满足,将区间长度加入队列
                    res.push_back(j-i+1);
                }
            }
        }
        sort(res.begin(),res.end(),greater<int>());//将区间长度从大到小排序
        return res.size()<K?-1:res[K-1];//选择第K大长度
    }
    
    int judge(int l,int r,vector<int> A,int num){
        int mi=N;//取[l,r]区间的最小值
        for(int i=l;i<=r;i++){
            mi=min(mi,A[i]);
        }
        
        for(int i=0;prime[i]<=mi;i++){//遍历素数表,判断该素数是否可行
            int flag=0;
            for(int j=l;j<=r;j++){
                if(A[j]%prime[i]!=0){//不能整除,则这个素数不满足,舍弃
                    flag=1;
                    break;
                }
            }
            if(flag==0)
                num--;
            if(num==0)
                return 1;
        }
        return 0;
    }
    
    void getPrime(){//线性筛素数O(n)
        int num=0;//素数的个数
        memset(isPrime,true,sizeof(isPrime));
        for(int i=2;i<=N;i++){
            if(isPrime[i]){
                prime.push_back(i);
                num++;
            }
            for(int j=0;j<num&&i*prime[j]<=N;j++){
                isPrime[i*prime[j]]=false;
                if(i%prime[j]==0)
                    break;
            }
        }
    }
    
};




时间复杂度:
空间复杂度: