力扣(LeetCode)计数质数 个人题解

2023-05-13,,

统计所有小于非负整数 质数的数量。

示例:

输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

一般方法,也就是一般人都会用的,将数从2到它本身逐个比较是否能被整除,就能得到结果。但这种方法复杂度是在0(n2)所以无法AC。

但是通过数学特性可以了解到,最多只要判断到这个数的开方数的时候,就可以知道这个数是否为质数了,所以复杂度减少了一半,也就可以让代码AC,但是时间用时也是很大的。

评论区学到的方法是,从2开始,剔除2到n中所有2的倍数,因为2的倍数都是非质数,然后找到3,同样剔除3的所有倍数,依次类推,得到最后的答案。

当然也可以应用数学特性将这个过程缩短,代码中不再演示

代码如下:(逐个比较)

import math

class Solution:
def isPrime(self, n: int) -> bool:
for i in range(2, math.floor(math.sqrt(n))+1):
if n % i == 0:
return False
return True def countPrimes(self, n: int) -> int:
count = 0
for i in range(2, n):
if Solution.isPrime(self, i):
count += 1
return count

代码如下:(剔除倍数)

class Solution:
def countPrimes(self, n: int) -> int:
if n < 3:
return 0
else:
isPrime = [1] * n
isPrime[0], isPrime[1] = 0, 0
for i in range(2, n):
t = 2
if isPrime[i] == 1:
while i*t < n:
isPrime[i*t] = 0
t += 1
return sum(isPrime)

剔除倍数的优化版本,摘自评论区:

# author: https://leetcode-cn.com/yuan-lei-yang/

def countPrimes(self, n: int) -> int:
if n < 3:
return 0
else:
# 首先生成了一个全部为1的列表
output = [1] * n
# 因为0和1不是质数,所以列表的前两个位置赋值为0
output[0],output[1] = 0,0
# 此时从index = 2开始遍历,output[2]==1,即表明第一个质数为2,然后将2的倍数对应的索引
# 全部赋值为0. 此时output[3] == 1,即表明下一个质数为3,同样划去3的倍数.以此类推.
for i in range(2,int(n**0.5)+1):
if output[i] == 1:
output[i*i:n:i] = [0] * len(output[i*i:n:i])
# 最后output中的数字1表明该位置上的索引数为质数,然后求和即可.
return sum(output)

力扣(LeetCode)计数质数 个人题解的相关教程结束。

《力扣(LeetCode)计数质数 个人题解.doc》

下载本文的Word格式文档,以方便收藏与打印。