素数筛选(从朴素到优化)

朴素做法

利用枚举的思想

从2开始一直到n,每次循环都把当前枚举的这个数到n之间所有的倍数全部删掉,那么最后剩下的就是质数了

const int N=1000100;// 数据范围
bool st[N];//用来记录每个数是否被删除
int prime[N];//用来记住所有的质数
int cnt;//用来统计个数
// 最小的一个素数是  2
for(int i = 2;i <= n;i++){
     if(!st[i]){//如果说这个数没有被删除掉的话,那么这个数就是质数
         prime[cnt++]=i;//这里用来记住用到了prime数组中的哪一个下标,如果只是数量的话,那么最后输出cnt就好了
      }
    //开始枚举,i的所有倍数,如果找到了就把这个点标记成true
      for(int j = i+i;j <= n;j=j+i){
            st[j]=true;
       }
}
//最后只要枚举prime数组就能得到[1,n]中所有的素数

埃式优化

不用每个点都进行枚举,如果说这个点之前已经被删除了,那意味着这个点已经不是质数了,我们就不需要进行枚举这个数的倍数,从而可以,减少循环的次数,进而降低时间复杂度

const int N=1000100;// 数据范围
bool st[N];//标记每个点是不是已经被删除了
int prime[N];
int cnt;
for(int i = 2;i <= n;i++){
    if(!st[i]){ //如果说,当前这个点没有被删除,说明他就是一个质数
        prime[cnt++] = i;//用来记录所有的素数
        for(int j = i+i;j <= n;j=j+i){
            st[j] = true;
        }
     }  
}

线性优化

x会被其最小的质因子筛去

const int N=1000100;
bool st[N];
int cnt;
int primes[N];    // primes[]存储所有素数
for (int i = 2; i <= n; i ++ ){
     if (!st[i]){
         primes[cnt ++ ] = i; 
     }
     for (int j = 0; primes[j] <= n / i; j ++ ) {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
}

204.计数质数

朴素做法

class Solution {
    public int countPrimes(int n) {
        int res  = 0 ;
        boolean[] st  = new boolean[n+1];
        for(int i = 2 ;i < n;i++){
            if(!st[i]) res++;
            for(int j  = i ;j<n;j+=i){
                st[j] = true;
            }
        }
        return res;
    }
}

埃式筛法

class Solution {
    public int countPrimes(int n) {
        int res  = 0 ;
        boolean[] st  = new boolean[n+1];
        for(int i = 2 ;i < n;i++){
            if(!st[i]){
                res++;
                for(int j  = i ;j<n;j+=i){
                    st[j] = true;
                }
            } 
        }
        return res;
    }
}

线性筛法

class Solution {
    // 线性筛法
    public int countPrimes(int n) {
        List<Integer> primes = new ArrayList<>();
        boolean[]st = new boolean[n+1];
        for(int i = 2;i < n;i++){
            if(!st[i]) primes.add(i);
            for(int j = 0;i * primes.get(j)< n;j++){
                st[i*primes.get(j)] = true;
                if(i%primes.get(j) == 0) break;
            }
        }
        return primes.size();
    }
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佩奇inging

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值