标签:return int 质数 ++ 计数 算法 result 整除
算法-计数质数
1 题目概述
1.1 题目出处
https://leetcode-cn.com/problems/count-primes/
1.2 题目描述
2 暴力枚举
2.1 思路
根据质数性质:只能被1和他本身这两个数整除的数称为质数。
2.2 代码
class Solution {
public int countPrimes(int n) {
int result = 0;
if(n < 2){
return result;
}
for(int i = 2; i < n; i++){
if(isPrime(i)){
result++;
}
}
return result;
}
private boolean isPrime(int n){
for(int i = 2; i * i <= n; i++){
if(n % i == 0){
return false;
}
}
return true;
}
}
2.3 复杂度
3 暴力枚举-优化
3.1 思路
根据质数性质:只能被1和他本身这两个数整除的数称为质数。
但还可以考虑:
- 提前结束筛选
代码中i * i <= n
即为最多只考虑开方数。比如我们这里命 a = i, b = i 。如果a 继续增大,则如果 c = n 整除 a,那么c 必然小于 b ,但 b 此时 小于 a了,肯定已经被判断过了。 - 最先考虑是否能被2整除,如果能则为合数;否则从3开始,每次加2,判断是否整除。
因为只要不能被2整除,则肯定不能被其他偶数整除。只需要判断其他奇数即可。
3.2 代码
class Solution {
public int countPrimes(int n) {
int result = 0;
if(n < 2){
return result;
}
if(n > 2){
result++;
}
for(int i = 2; i < n; i++){
if(isPrime(i)){
result++;
}
}
return result;
}
private boolean isPrime(int n){
if(n % 2 == 0){
return false;
}
for(int i = 3; i * i <= n; i = i + 2){
if(n % i == 0){
return false;
}
}
return true;
}
}
3.3 时间复杂度
4 埃氏筛
4.1 思路
不需要将合数的倍数标记为合数的原因是,合数的倍数肯定已经被该合数的质因数某个倍数标记过了。
4.2 代码
class Solution {
public int countPrimes(int n) {
if(n < 2){
return 0;
}
if(n == 2){
return 0;
}
int result = 0;
int[] primes = new int[n];
Arrays.fill(primes, 1);
for(int i = 2; i < n; i++){
if(primes[i] == 1){
result++;
// 防止i * i 超过 Integer.MAX_VALUE,所以转为long来比较
if((long) i * i >= n){
continue;
}
for(int j = i * i; (j > 0) && (j < n); j += i){
primes[j] = 0;
}
}
}
return result;
}
}
4.3 复杂度
5 线性筛
5.1 思路
5.2 代码
5.3 时间复杂度
参考文档
标签:return,int,质数,++,计数,算法,result,整除 来源: https://blog.csdn.net/baichoufei90/article/details/110521917
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。