[204] 计数质数

链接:计数质数

1.判断一个数是否为素数的方法

  1. 2~n-1判断是否有n的因数,如果不能找到因数,则n是素数。O(n)
def is_prime(n):
    for e in range(2, n):
        if n % e == 0:
            return False
    else:
        return True
  1. 2~\sqrt{n}判断是否有n的因数,如果不能找到因数,则n是素数。O(\sqrt{n})
def is_prime(n):
    for e in range(2, int(sqrt(n))+1):
        if n % e == 0:
            return False
    else:
        return True

2.标记小于数的全部素数

对于这个问题,可以对2~n-1中每个元素使用O(\sqrt{n})的算法进行判断,整体的时间复杂度为O(n\sqrt{n}),在本题的case中会超时。

这个问题可以使用埃式筛算法来快速找到小于n的所有素数,具体流程如下

  1. 创建一个长度为n的bool标记数组,除了0,1两个位置外,其余元素初始化为True。
  2. 当我门找到一个素数x时,对这个素数的所有倍数,都置为False,即2x,3x,\cdots,\lfloor \frac{n}{x} \rfloor x这些数都是合数。这里有个优化点,即当x 比较大时(比如x=7),2x,3x,5x对应的14,21,35,会在之前的遍历中被置为False,因此只需要对x^2, x(x+1), \cdots, \lfloor \frac{n}{x} \rfloor x进行置False操作。
  3. x的范围,因为对每个素数x,我们是从 x^2 开始置False,当x^2 > n时,便没有数可以置False,因此遍历时x的范围是2~\sqrt(n)
class Solution:
    def countPrimes(self, n: int) -> int:
        if n < 2:
            return 0

        nums = [True] * n
        nums[0], nums[1] = False, False
        
        for i in range(2, int(n**0.5)+1):
            if nums[i]:
                for j in range(i*i, n, i):
                    nums[j] = False
        
        return sum(nums)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容