题目来源
题目描述
class Solution {
public:
int countPrimes(int n) {
}
};
题目解析
素数筛法
- 先把所有整数列出来,然后把2的倍数全部剔除,然后把3的倍数全部剔除…
- 遍历所有素数,如果没有被划去,它一定是素数,然后把它的倍数也划去
class Solution {
public:
int countPrimes(int n) {
// 写程序时要时刻注意边界条件
if (n < 3){
return 0;
}
std::vector<bool> f(n, false); // < n
int count = n / 2; // 所有偶数都不要,还剩几个数
for (int i = 3; i * i < n; ++i) {
if(f[i]){
continue;
}
for (int j = i * i; j < n; j += 2 * i) {
if (!f[j]) {
--count;
f[j] = true;
}
}
}
return count;
}
};
埃氏筛
准备:
- 算术基本定理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积
- 若一个数可以进行因数分解,则得到的两个数一定是有一个>=sqrt(x),另一个<=sqrt(x).
算法步骤
N = 26,
- 1、列出所有序列
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 - 2、找到第一个素数:0,1不是素数【去掉】,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
- 3、将剩下的队列中,划掉2的倍数,序列变成:2 3 5 7 9 11 13 15 17 19 21 23 25
- 4、如果这个序列中最大数小于最后一个标出的素数的平方,那么剩下的所有的数都是素数,否则回到第二步。
- 5、本例中,因此25大于2的平方,我们返回第二步:
- 6、剩下的序列中第一个素数是3,将主序列中3的倍数划掉,主序列变成:2 3 5 7 11 13 17 19 23 25
- 7、我们得到的素数有:2,3
- 8、25仍然大于3的平方,所以我们还要返回第二步:
序列中第一个素数是5,同样将序列中5的倍数划掉,主序列成了:2 3 5 7 11 13 17 19 23
9、我们得到的素数有:2,3,5 。
10、因为23小于5的平方,跳出循环.
结论:2到25之间的素数是:2 3 5 7 11 13 17 19 23。
class Solution {
public:
int countPrimes(int n) {
// 写程序时要时刻注意边界条件
if (n < 2){
return 0;
}
std::vector<int> arr(n, 0);// 0 表示都是素数
arr[0] = arr[1] = 1; // 1 表示不是素数
for (int i = 2; i <= std::sqrt(n - 1); i++){
if (arr[i] == 0){ // 没有被圈出来
// 去掉倍数
for (int j = i * 2; j <= n - 1 ; j = j + i){ // 2 的倍数去掉, 3的倍数去掉,5的倍数去掉
arr[j] = 1; // 去掉倍数
}
}
}
int ans = 0;
for (int value : arr) {
if (value == 0) {
ans++;
}
}
return ans;
}
};
优化暴力
假如一个数为 9 ,那么其二分之一(4.5)后的数都可以不用进行计算,因为肯定是有余的 。事实上情况会比这更好一些:对正整数 n ,如果用 2 到 √n 之间(包含边界)的所有整数去除,均无法整除,则 n 为质数
class Solution {
public:
int countPrimes(int n) {
int ans = 0;
for (int i = 2; i < n; i++){
if (Primes(i)){
ans++;
}
}
return ans;
}
static bool Primes(int n){
bool flag = true;
int t = (int)std::sqrt(n);
for (int i = 2; i < t + 1; i++){
if (n % i == 0){
flag = false;
break;
}
}
return flag;
}
};
类似题目
题目 | 思路 |
---|---|
leetcode:204. 小于n的质数的数量 Count Primes | |
leetcode:279. 完全平方数 Perfect Squares |