《leetCode》:Count Primes

题目

Description:

Count the number of prime numbers less than a non-negative number, n.

题目大意:统计小于n的素数的个数

质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,
换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。
根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积;而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的。最小的质数是2。

思路一:暴力统计

int countPrimes(int n) {
     if(n<=2){
         return 0;
     }
     if(n==3){//即只有2这一个素数
         return 1;
     }
     if(n==4){//包含2和3两个素数
         return 2;
     }
     int index=2;//包含2和3两个素数
     for(int i=4;i<n;i++){
         int j=2;
         int temp=i>>1;
         for (;j<=temp;j++){
             if(i%j==0){
                 break;
             }
         }
         if(j>temp){//即为素数
             index++;
         }
     }
     return index;
 }

暴力搜索思路虽然正确,但是报超时错误

思路二

来自于题目下面的思路如下:https://leetcode.com/problems/count-primes/

We start off with a table of n numbers. Let's look at the first number, 2. 
We know all multiples of 2 must not be primes, so we mark them off as non-primes. 
Then we look at the next number, 3. Similarly, all multiples of 3 such 
as 3 × 2 = 6, 3 × 3 = 9, ... must not be primes, 
so we mark them off as well. Now we look at the next number, 4, which 
was already marked off. What does this tell you? Should you mark off all multiples of 4 as well?

4 is not a prime because it is divisible by 2, which means all 
multiples of 4 must also be divisible by 2 and were already marked off. 
So we can skip 4 immediately and go to the next number, 5. 
Now, all multiples of 5 such as 5 × 2 = 10, 5 × 3 = 15, 5 × 4 = 20, 5 × 5 = 25, ... can be marked off. 
There is a slight optimization here, we do not need to start from 5 × 2 = 10. 
Where should we start marking off?

素数不能被比它小的整数整除, 建一个bool 数组, 从2开始, 把其倍数num小于N的arr[num]令为true.即,将2的倍数,3的倍数,4的倍数(也就是2的倍数,重复)…
最后统计这个数组中为false的个数。


int countPrimes(int n) {
    if(n<=2){
        return 0;
    }
    bool *arr=(bool *)malloc(n*sizeof(bool));
    if(arr==NULL){
        exit(EXIT_FAILURE);
    }
    memset(arr,false,n*sizeof(bool));
    for(int i=2;i*i<n;i++){//依次将i=2,3,4,5,。。。的倍数全部设为true。最后剩下的就是素数 
        if(!arr[i]){
            for(int j=i;i*j<n;j++){
                arr[i*j]=true;
            }
        }
    }
    int count=0;
    for(int i=2;i<n;i++){//从2开始 
        if(!arr[i]){
            count++;
        }
    }

    return count; 


}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值