Count the number of prime numbers less than a non-negative number, n.
Example:
Input: 10 Output: 4 Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
典型的一道求<n的所有质数问题,(解法和思路适用于所有关于求质数的问题),质数只能被1和自身整除
总结一下最普遍的求质数方法(一步一步进阶),参考,不讲原理了:
1 每个数i ,从2~i-1都除一下,都不能整除说明这个数是质数
2 知道偶数肯定不是质数(除了2),所以对每个奇数,从2~i-1都除一下,都不能整除说明这个数是质数
3 对每个(奇)数,从2~i/2都除一下,都不能整除说明这个数是质数
4 对每个(奇)数,从2~都除一下,都不能整除说明这个数是质数
5 只要尝试小于的质数即可,即对每个(奇)数,从2~的质数都除一下,都不能整除说明这个数是质数
1 先说一个超时算法(Time Limit Exceeded)用的第四种方法依旧超时,n = 999983时
class Solution:
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
if n <=2 :return 0
num = 1
for i in range(3,n,2):
flag = 0
for j in range(2,math.ceil(math.sqrt(i))+1):
if i % j == 0:
flag = 1
break
if flag == 0: num += 1
return num
2 使用第5种办法(Time Limit Exceeded)
从3~n-1 遍历每个奇数,计算它是否是质数,计算办法是对每个奇数i,除2~i-1的质数,都不能整除则是i是质数
所以需要记录哪些数是质数
class Solution:
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
if n <=2 :return 0
primes = [2]
for i in range(3,n,2): #odd number
flag = 0
test = [k for k in primes if k <= math.sqrt(i)]
for j in test:
if i%j == 0:
flag = 1
break
if flag == 0:primes.append(i)
return len(primes)
3 筛法 Accepted
首先,2是公认最小的质数,所以,先把所有2的倍数去掉;然后剩下的那些大于2的数里面,最小的是3,所以3也是质数;然后把所有3的倍数都去掉,剩下的那些大于3的数里面,最小的是5,所以5也是质数……
上述过程不断重复,就可以把某个范围内的合数全都除去(就像被筛子筛掉一样),剩下的就是质数了。
class Solution:
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
if n <=2 :return 0
isprime = [1] * n #index from 0 ~ n-1
for i in range(2,n):
if isprime[i] == 1:
j = 2 * i
while j < n:
isprime[j] = 0
j += i
return sum(isprime)-2 #isprime[0] & isprime[1] is redundant
class Solution:
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
if n <=2 :return 0
isprime = [1] * n
for i in range(2,n):
if isprime[i] == 1:
for j in range(2,math.ceil(n/i)):
if i*j < n:isprime[i * j] = 0
return sum(isprime) -2