204计数质数

题目:统计所有小于非负整数 的质数的数量.

来源: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
View Code

法二:别人的代码

思路:从前往后遍历,如果一个数是质数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)
View Code

ttt

posted on 2020-01-31 11:35  吃我一枪  阅读(201)  评论(0编辑  收藏  举报

导航