第一种方法 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;
}
}

posted on 2016-01-10 13:03  爱推理的骑士  阅读(131)  评论(0编辑  收藏  举报