第一种方法 The Sieve of Eratosthenes is one of the most efficient ways to find all prime numbers up to n.
The Sieve of Eratosthenes uses an extra O(n) memory and its runtime complexity is O(n log log n)
创建一个length = n的boolean数组 isPrime,每个元素初始化为true;
k = 2:(n-1),如果当前数k是prime,把 k^k - (n-1)/k *k的数 对映的 isPrime = false;
最后计算 从2到n-1 isPrime == true的个数。
代码:
public class Solution {
public int countPrimes(int n) {
boolean[] isPrimes = new boolean[n];
for(int i = 0; i < isPrimes.length; i++){
isPrimes[i] = true;
}
for(int k = 2; k <= (n-1)/k; k++){
if(isPrimes[k] == true){
for(int i = k; i <= (n-1)/k; i++){
isPrimes[i*k] = false;
}
}
}
int count = 0;
for(int i = 2; i< isPrimes.length; i++){
if(isPrimes[i] == true) count++;
}
return count;
}
}
还可以用DP来解决。
public class Solution {
public int countPrimes(int n) {
int count = 0;
int squareRoot = 1;
int number = 2;
List<Integer> list = new ArrayList<>();
for(int i = number; i < n; i++){
boolean isPrime = true;
if(squareRoot * squareRoot < i) squareRoot++;
for(int j = 0; j < list.size() && list.get(j) <= squareRoot;j++){
if(i%list.get(j) == 0){
isPrime = false;
break;
}
}
if(isPrime == true){
list.add(i);
count++;
}
}
return count;
}
}
Runtime: O(n*sqrt(n)/log(n))
最后,记录下最原始的求prime的方法 0-sqrt(n):
public class Solution {
public int countPrimes(int n) {
int count = 0;
int squareRoot = 1;
int number = 2;
for(int i = number; i < n; i++){
boolean isPrime = true;
for(int divisor = 2; divisor <= (int) (Math.sqrt(i)) ; divisor++){
if(i%divisor == 0){
isPrime = false;
break;
}
}
if(isPrime == true){
count++;
}
}
return count;
}
}