204计数质数
题目:统计所有小于非负整数 n 的质数的数量.
来源:https://leetcode-cn.com/problems/count-primes/
法一:自己的超时代码
思路:和官方的方法事实上一样,但是代码没有用标记0 1的方法,导致很费时.删除每个质数的倍数时,都需要判断是否存在,如果是用标记0 1的方法不会出现这种问题,要学会这个切片技巧.
import math class Solution: def countPrimes(self, n: int) -> int: if n in [1,2]: return 0 amount = [i+1 for i in range(1,n-1)] ans = 0 # def judge(a): # for j in range(2,int(math.sqrt(a))+1): # # 如果为合数,返回False # if (a % j) == 0: # return False # return True while amount: a = amount.pop(0) ans += 1 k = a while k * a <= n: if k*a in amount: amount.remove(k*a) k += 1 return ans
法二:别人的代码
思路:从前往后遍历,如果一个数是质数k,则把它后面所有大于等于k倍的数都标记为合数.如果一个数的标记为1,则其一定是质数,因为如果其为合数,前面一定存在它的因子,会把它标记为0.
class Solution: def countPrimes(self, n: int) -> int: if n < 2: return 0 # 用1作为标记 isPrimes = [1] * n # 0和1不是质数,设置为0 isPrimes[0] = isPrimes[1] = 0 # 这是一个定理:在 2 到 根号n 的范围内,当一个数是质数,将它所有的比n小的倍数设置成0 for i in range(2, int(n ** 0.5) + 1): if isPrimes[i] == 1: # 这里很重要,i-1 * i 已经被前面的i-1删除了 # 注意左边的这个n可以任意大 isPrimes[i * i: n: i] = [0] * len(isPrimes[i * i: n: i]) #现在每个质数位的flag为1,其余的位数为0.由于我们不需要知道质数是什么只要总数,因此直接返回list里面所有1的和就行。 return sum(isPrimes) if __name__ == '__main__': duixiang = Solution() a = duixiang.countPrimes(50) print(a) k = [1,2,3,4,5,6,7,8,9] k[0:20:2] = [0] * 5 print(k)
ttt