题目链接:Count Primes
Description:
Count the number of prime numbers less than a non-negative number, n.
References:
这道题的要求是统计小于n的非负整数中有多少质数。
常用的快速方法是埃拉托斯特尼筛法:给出要筛数值的范围n,找出sqrt(n)以内的素数p1, p2, …, pk。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个素数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个素数5筛,把5留下,把5的倍数剔除掉;不断重复下去……
-
Plan A
采用vector构造长度为n的数组,进行筛选,时间321ms。
时间复杂度:O(n(logn)(loglogn))
空间复杂度:O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution
{
public:
int countPrimes(int n)
{
vector<bool> prime(n, true);
int sqrn = sqrt(n);
for(int i = 2; i <= sqrn; ++ i)
if(prime[i])
for(int j = i * i; j < n; j += i)
prime[j] = false;
int res = 0;
for(int i = 2; i < n; ++ i)
if(prime[i])
++ res;
return res;
}
};
-
Plan B
采用new操作构造长度为n的数组,进行筛选,时间59ms。
时间复杂度:O(n(logn)(loglogn))
空间复杂度:O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution
{
public:
int countPrimes(int n)
{
bool *prime = new bool[n];
for(int i = 0; i < n; ++ i)
prime[i] = true;
int sqrn = sqrt(n);
for(int i = 2; i <= sqrn; ++ i)
if(prime[i])
for(int j = i * i; j < n; j += i)
prime[j] = false;
int res = 0;
for(int i = 2; i < n; ++ i)
if(prime[i])
++ res;
return res;
}
};
-
Plan C
采用new操作构造长度为n的数组,进行筛选(一次遍历),时间45ms。
时间复杂度:O(n(logn)(loglogn))
空间复杂度:O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution
{
public:
int countPrimes(int n)
{
bool *visited = new bool[n];
int sqrn = sqrt(n), res = 0;
for(int i = 2; i < n; ++ i)
if(!visited[i])
{
++ res;
if(i <= sqrn)
for(int j = i * i; j < n; j += i)
visited[j] = true;
}
return res;
}
};
-
Plan D
采用new操作构造int数组,位操作统计,时间65ms。
时间复杂度:O(n(logn)(loglogn))
空间复杂度:O(n)
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
26
27
28
29
30
31
32
33
34
35
36
class Solution
{
public:
int countPrimes(int n)
{
int bit_num = sizeof(int) * 8;
int *is_prime = new int[n / bit_num + 1];
is_prime[0] = -1 & ~3;
for(int i = 1; i < n / bit_num + 1; ++ i)
is_prime[i] = -1;
int sqrn = sqrt(n);
for(int i = 2; i <= sqrn; ++ i)
if(is_prime[i / bit_num] & (1 << i % bit_num))
for(int j = i * i; j < n; j += i)
is_prime[j / bit_num] &= ~(1 << j % bit_num);
int res = 0;
for(int i = 0; i < n / bit_num; ++ i)
res += hammingWeight(is_prime[i]);
for(int i = n / bit_num * bit_num; i < n; ++ i)
if(is_prime[i / bit_num] & (1 << i % bit_num))
++ res;
return res;
}
private:
int hammingWeight(int n)
{
n = (n & 0x55555555) + (n >> 1 & 0x55555555);
n = (n & 0x33333333) + (n >> 2 & 0x33333333);
n = (n & 0x0F0F0F0F) + (n >> 4 & 0x0F0F0F0F);
n = (n & 0x00FF00FF) + (n >> 8 & 0x00FF00FF);
n = (n & 0x0000FFFF) + (n >> 16 & 0x0000FFFF);
return n;
}
};