204. 计数质数
题目描述
统计所有小于非负整数 n 的质数的数量。
示例 1:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
示例 2:
输入:n = 0
输出:0
示例 3:
输入:n = 1
输出:0
提示:
0 <= n <= 5 * 106
解题
法一:枚举
想多了,python枚举直接超时
法二:筛
我们要求n以内的质数。
用一个列表来标记这些数的性质(质数是0,合数是1)。
从2开始,2肯定是质数,我们计数并将2的倍数标记为合数。
同理,3是质数,计数,将3的倍数标记为合数。
4是合数,已经被标记过。
5未被标记,是质数。。。
我们通过标记,把合数筛走,只留下为标记的是质数。然后计数。
class Solution:
def countPrimes(self, n: int) -> int:
if n <= 2: return 0
if n == 3: return 1
res, tem = 0, [0]*n
for num in range(2, n):
if tem[num] == 1:
continue
else:
res += 1
knum = 2*num
while knum < n:
tem[knum] = 1
knum += num
return res
法三:线性筛
核心思想是对标记的过程继续优化,避免重复标记;
优化的原理是基于数学的,类似于反向的质因数分解。
代码写不出来了,cv一份别人的做个参考
class Solution:
def countPrimes(self, n: int) -> int:
if n < 2:
return 0
prime = [-1 for _ in range(n)]
pn = 0
mark = [True for _ in range(n)]
mark[0] = mark[1] = False
for x in range(2, n):
if mark[x] == True:
prime[pn] = x
pn += 1
pi = 0
while pi < pn and x * prime[pi] < n: #可以理解成质因数分解的反过程
y = x * prime[pi]
mark[y] = False
pi += 1
return pn