给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
提示:
核心问题就是如何高效率的判断一个数是不是质数。
假如一个数n可以被x整除,商为y,那么x和y中的较小的一个数肯定小于等于n^0.5(也就是n的平方根),所以判断一个数是否为质数,只需要遍历2 - n^0.5之间的数能否被n整除即可,如果可以整除那么n就不是质数,否则就是质数。
class Solution: def countPrimes(self, n: int) -> int: def isPrimes(num: int) -> bool: '判断数字num是否为质数' i = 2 while i*i <= num: if num % i ==0: return False i += 1 return True count = 0 for i in range(2,n): if isPrimes(i): count += 1 return count
首先遍历小于n的数字,挨个判断每个数是否为质数。
O(n^(3/2))
。算法中并没有使用额外的大型数据结构,除了几个变量用于计数和迭代。因此,空间复杂度为 O(1),即常数空间复杂度
class Solution: def countPrimes(self, n: int) -> int: if n < 2: return 0 l = [1]*n l[0] = 0 l[1] = 0 for i in range(2, int(n**0.5+1)): if l[i] == 1: l[i*i:n:i] = [0] * ((n-1-i*i)//i+1) return sum(l)
默认所有数都是质数,并将默认状态(1:质数,0:不是质数)保存在数组,然后查找不是质数的数字。
如题需要查询所有小于n的非负整数质数,那么如果n不是质数,那么n肯定可以被小于等于n0.5的数整除,同理,如果一个小于n的数不是质数,那么它肯定可以被被小于等于n0.5的某个数整除,所以我们只需遍历2 - n^0.5之间的数,并找出这些数的整数倍的数字(不是质数的数字),并修改数字中的状态,最后计算数组的和就是小于n的质数的个数。
综合以上,整个算法的时间复杂度为 O(n log log n)
。
算法使用了一个长度为 n 的列表 l 来存储每个数字是否为质数的信息,因此空间复杂度为 O(n)
。