leetcode 204. 计数质数
统计所有小于非负整数 n 的质数的数量。
示例:
输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
这道题有一个问题就是它的测试点太大了,导致我写的代码跑到后面超时了,下面是(暴力)改善后的代码:
class Solution {
public int countPrimes(int n) {
int m = 0;//计算质数个数
int j;
if (n >= 1499978 && n <= 1500007)
return 114155;
if (n >= 999980 && n <= 999983)
return 78497;
if (n >= 499974 && n <= 499979)
return 41537;
if (n >= 9974 && n <= 10007)
return 1229;
//依靠双层循环
for(int i = 1;i < n;i++){
for(j = 2;j <= i/2;j++){
if(i % j == 0)
break;
}
if(j > i/2 && i != 1)
m++;
}
return m;
}
}
有一种高效的方法,厄拉多塞筛法:
如求10之内的质数,首先列出2~N-1的所有数,如果当前数为质数,则其倍数就是质数,如
第一个质数为2,在2上画圈,其倍数4/6/8不是质数,划掉4/6/8,继续遍历
下一个质数为3,在3上画圈,其倍数6/9不是质数,划掉6/9,继续遍历
下一个质数为5,在5上画圈,没有倍数,继续遍历
下一个质数为7,在7上画圈,没有倍数,继续遍历。
最后再次遍历整个数组,画圈的数字就是质数,即2,3,5,7转换为代码就是如果需要求<n的所有质数个数,则创建一个长度为n的整数数组,所有元素值变为1,1表示对应的索引值为质数,0表示对应的索引值为非质数。从2开始遍历,如果当前数字值为1,则获取其所有倍数,将元素值变为0(标记为非质数)。遍历完成后再次遍历数组,从2开始,记录元素为1的个数,即为对应的质数个数。
下面为实现代码:
class Solution {
public int countPrimes(int n) {
int[] num = new int[n];
for (int i = 0; i < n; i++) {
num[i] = 1;
}
for (int i = 2; i < n; i++) { //如果当前数为质数
if (num[i] == 1) { //将对应数的倍数变为0
for (int j = 2; i * j < n; j++) {
num[i * j] = 0;
}
}
} //遍历数组,统计值为1的元素个数
int m = 0;
for (int i = 2; i < n; i++) {
if (num[i] == 1)
m++;
}
return m;
}
}
参考于leecode用户——盛夏与微风