1 class Solution { 2 public int countPrimes(int n) { 3 int count = 0; 4 for(int i = 2; i < n; i++){ 5 if(isPrime(i)) count++; 6 } 7 return count; 8 } 9 10 public boolean isPrime(int n){ 11 for(int i = 2; i < n; i++){ 12 if(n % i == 0) return false; 13 } 14 return true; 15 } 16 }
一上来呢 肯定是想到这一点 逻辑上没有问题 但是提交超时了 时间复杂度O(N^2)
1 class Solution { 2 public int countPrimes(int n) { 3 int count = 0; 4 for(int i = 2; i < n; i++){ 5 count += isPrime(i)?1:0; 6 } 7 return count; 8 } 9 10 public boolean isPrime(int n){ 11 for(int i = 2; i * i <= n; i++){ 12 if(n % i == 0) return false; 13 } 14 return true; 15 } 16 }
优化一下 假设y是x的因数 那么x/y也一定是 x的因数 所以我们只要检测y或者x/y中较小的那一个就可以了
当y趋近于 √x 时 我们需要判断的区间最小[2, √x] 单次判断的时间复杂度降低到O(√N) 总时间复杂度O(N√N)
1 public int countPrimes(int n) { 2 boolean[] notPrime = new boolean[n]; 3 int count = 0; 4 for (int i = 2; i < n; i++) { 5 if (!notPrime[i]) { 6 count++; 7 //将当前素数的倍数依次标记为非素数 8 for (int j = 2; j * i < n; j++) { 9 notPrime[j * i] = true; 10 } 11 } 12 } 13 return count; 14 }
以空间换时间
从2开始 把2的倍数依次标记为非素数
从3开始 把3的倍数依次标记为非素数
......
时间复杂度O(NloglogN)太复杂 不会算了 力扣抄过来的
https://leetcode-cn.com/problems/count-primes/solution/ji-shu-zhi-shu-by-leetcode-solution/
力扣还有一个方法三 线性筛 有.复杂 本菜鸡放弃了++
原文:https://www.cnblogs.com/doomslayer/p/14078610.html