leetcood学习笔记-204-计算质数
2024-10-07 18:29:08
题目描述:
第一次提交;(超时):
class Solution:
def countPrimes(self, n: int) -> int:
count = 0
for i in range(2,n):
for j in range(2,i+1):
if i%j == 0 and j!=i:
break
if j==i:
count+=1
return count
别人家的:
这题搜到一个非常牛逼的算法,叫做厄拉多塞筛法. 比如说求20以内质数的个数,首先0,1不是质数.2是第一个质数,然后把20以内所有2的倍数划去.2后面紧跟的数即为下一个质数3,然后把3所有的倍数划去.3后面紧跟的数即为下一个质数5,再把5所有的倍数划去.以此类推. 代码的实现上用了非常好的技巧: 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]) #注意[0]
# 最后output中的数字1表明该位置上的索引数为质数,然后求和即可.
return sum(output)
在上面遍历索引的时候用到了一个非常好的技巧. 即i是从(2,int(n**0.5)+1)而非(2,n).这个技巧是可以验证的,比如说求9以内的质数个数,那么只要划掉sqrt(9)以内的质数倍数,剩下的即全为质数. 所以在划去倍数的时候也是从i*i开始划掉,而不是i+i.
最新文章
- Github快速入门手册
- POJ 2318 TOYS【叉积+二分】
- Ubuntu Navicat for MySQL安装以及破解方案
- 年前辞职-WCF入门学习(3)
- C#中的委托、事件和设计模式(转载)
- cocos2dx 手势识别
- dos常用文件操作命令
- 【转】Mac不能复制拷贝写入文件到移动硬盘,U盘怎么办 |
- MSDN Webcast 系列课程
- android常用软件下载资源链接
- 国内好用的公用DNS 服务器。
- 基本介绍LINUX远程PC软件:PUTTY、SecureCRT、X-Manager
- poj3067 Japan 树状数组求逆序对
- eclipse中 web项目缺少tomcatl lib的解决办法
- uptime 命令详解
- 【笔记】css浮动的一些个人见解
- CURL学习总结(1)
- 在.NET开发中的单元测试工具之(1)——NUnit
- 029、限制容器的block IO(2019-01-24 周四)
- SAS对数据变量的处理