🔎概述
给定整数 n ,返回所有小于非负整数 n 的质数的数量
🔎题解
🌻解法1(朴素解法)
public int countPrimes(int n) { int count = 0; for (int i = 2; i < n; i++) { if(isPrime3(i)) count++; } return count; } private boolean isPrime(int num) { for (int i = 2; i <= Math.sqrt(num); i++) { if(num % i == 0) return false; } return true; }
- 对于一个正整数9,我们只需要判断9对于2-9的平方根的数字取余是否为0,即可判断该数是否为质数
- 对于质数,是指该数是否能仅被1和它本身整除,所以从2开始
- 为什么是9的平方根,因为任何一个数都不可能分解成两个大于其平方根的数的乘积.肯定只能分解为一个大于或等于其平方根,另一个小于或等于其平方根.
显然,这种方法是不够高效的
下面介绍一种更为高效的方法
🌻解法2(埃氏筛)
public int countPrimes(int n) { int count = 0;//统计有多少个质数 boolean[] notPrime = new boolean[n];//0~n-1 for (int i = 2; i < n; i++) { if(notPrime[i]) {//如果不是质数,继续 continue; } count++;//是质数,个数+1 //这里用long因为题目给的数据范围是10^6,过大 //从2开始,j = i * i,即为i的最小倍数,那么i的倍数一定不是质数 //j += i,表示在i的最小倍数再加上i //j = 4,j += i(j = 6,8,10...),这些数字均不是质数 for (long j = (long)i * i; j < n; j += i) { notPrime[(int)j] = true; } } return count; }
- 埃氏筛
- 从最小的质数开始,它的倍数均不是质数(从2开始,4,6,8,10…均不是质数),将notPrime[j]标记位true
- 剩下的最小数字就是3,再将3的倍数依次标记为true(9,15)
- 重复上述步骤,直到遍历结束
- 剩下的未被标记的数字即为质数
🔎题目链接
🔎结尾
如果大家有什么不太理解的,可以私信或者评论区留言,一起加油