统计所有小于非负整数 n 的质数的数量。
示例:
输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
质数定义:质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。
解题方法:
一、根据质数的概念进行求解
遍历所有比n小的数,判断每个数是不是质数,进行统计
class Solution {
public int countPrimes(int n) {
int res=1;//从3开始计算,所以初始为1
if(n<3) return 0;
else
{
for(int i=3;i<n;i++)
{
if(i%2==0)
continue;
bool flag=true;//false表示不是素数
for(int j=3;j<=sqrt(i);j+=2)
{
if(i%j==0)
{
flag=false;
break;
}
}
if(flag)
{
res++;
}
}
}
return res;
}
};
二、厄拉多塞筛法
想要得到一个不大于N的数所有素数个数,可以先找到不超过根号N的所有素数,设2 = p1 < p2 < ......<pk ≤√N,然后在2,3,4......N里面进行下面的操作:
留下p1 = 2,把p1的倍数全部划掉,
再留下p2 ,把p2 的倍数全部划掉,
继续这一过程,直到留下pk,把pk的倍数全部划掉,
最后留下来就是不超过N的全体素数。
例:
N = 30 ,则取pk 为5,所以2到5的所有素数为2,3,5
第一遍 留下2,划去2的所有倍数
2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
第二遍 留下3,划去3的所有倍数
2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
第三遍 留下5,划去5的所有倍数
2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
剩余的数就是小于等于30的所有素数,即 2,3,5,7,11,13,17,19,23,29
代码思想:设置一个表来存放所有的小于n的数,找到第一个质数,将其在小于n的范围内的所有倍数的对应的标志位置为false,如果一个数的标志位被置为 false,则跳过次数,向下遍历,遍历完所有标志位为true的数即结束。最后所有标志位为true对应的数即为质数,true的个数就是质数的个数。
public int countPrimes(int n) {
vector<bool> num(n,true);
int res=0;
for(int i=2;i<=sqrt(n);i++)
{
if(num[i])
{
int k=2;
while(k*i<n)
{
num[k*i]=false;
k++;
}
}
}
for(int i=2;i<n;i++)
{
if(num[i])
res++;
}
return res;
}