| 
 | 1 | +// Source : https://leetcode.com/problems/count-primes/  | 
 | 2 | + | 
 | 3 | + | 
 | 4 | +/**********************************************************************************   | 
 | 5 | + *   | 
 | 6 | + * Description:  | 
 | 7 | + * Count the number of prime numbers less than a non-negative number, n.  | 
 | 8 | + *   | 
 | 9 | + * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases.  | 
 | 10 | + *   | 
 | 11 | + *   Let's start with a isPrime function. To determine if a number is prime, we need to check if   | 
 | 12 | + *   it is not divisible by any number less than n. The runtime complexity of isPrime function   | 
 | 13 | + *   would be O(n) and hence counting the total prime numbers up to n would be O(n2). Could we do better?  | 
 | 14 | + *     | 
 | 15 | + *   As we know the number must not be divisible by any number > n / 2, we can immediately cut the total   | 
 | 16 | + *   iterations half by dividing only up to n / 2. Could we still do better?  | 
 | 17 | + *     | 
 | 18 | + *   Let's write down all of 12's factors:  | 
 | 19 | + *   | 
 | 20 | + * 	2 × 6 = 12  | 
 | 21 | + * 	3 × 4 = 12  | 
 | 22 | + * 	4 × 3 = 12  | 
 | 23 | + * 	6 × 2 = 12  | 
 | 24 | + *   | 
 | 25 | + * As you can see, calculations of 4 × 3 and 6 × 2 are not necessary. Therefore, we only need to consider   | 
 | 26 | + * factors up to √n because, if n is divisible by some number p, then n = p × q and since p ≤ q, we could derive that p ≤ √n.  | 
 | 27 | + *   | 
 | 28 | + * Our total runtime has now improved to O(n1.5), which is slightly better. Is there a faster approach?  | 
 | 29 | + *   | 
 | 30 | + *	public int countPrimes(int n) {  | 
 | 31 | + *	   int count = 0;  | 
 | 32 | + *	   for (int i = 1; i < n; i++) {  | 
 | 33 | + *	      if (isPrime(i)) count++;  | 
 | 34 | + *	   }  | 
 | 35 | + *	   return count;  | 
 | 36 | + *	}  | 
 | 37 | + *	  | 
 | 38 | + *	private boolean isPrime(int num) {  | 
 | 39 | + *	   if (num <= 1) return false;  | 
 | 40 | + *	   // Loop's ending condition is i * i <= num instead of i <= sqrt(num)  | 
 | 41 | + *	   // to avoid repeatedly calling an expensive function sqrt().  | 
 | 42 | + *	   for (int i = 2; i * i <= num; i++) {  | 
 | 43 | + *	      if (num % i == 0) return false;  | 
 | 44 | + *	   }  | 
 | 45 | + *	   return true;  | 
 | 46 | + *	}  | 
 | 47 | + *     | 
 | 48 | + *   The Sieve of Eratosthenes is one of the most efficient ways to find all prime numbers up to n.   | 
 | 49 | + *   But don't let that name scare you, I promise that the concept is surprisingly simple.  | 
 | 50 | + *  | 
 | 51 | + *	[Sieve of Eratosthenes](http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)  | 
 | 52 | + *   | 
 | 53 | + *	[https://leetcode.com/static/images/solutions/Sieve_of_Eratosthenes_animation.gif]  | 
 | 54 | + *	[http://commons.wikimedia.org/wiki/File:Sieve_of_Eratosthenes_animation.gif]  | 
 | 55 | + *  | 
 | 56 | + *   Sieve of Eratosthenes: algorithm steps for primes below 121. "Sieve of Eratosthenes Animation"()   | 
 | 57 | + *   by SKopp is licensed under CC BY 2.0.  | 
 | 58 | + *  | 
 | 59 | + *      * [Skoop](http://de.wikipedia.org/wiki/Benutzer:SKopp)  | 
 | 60 | + *	* [CC BY 2.0](http://creativecommons.org/licenses/by/2.0/)  | 
 | 61 | + *   | 
 | 62 | + * We start off with a table of n numbers. Let's look at the first number, 2. We know all multiples of 2   | 
 | 63 | + * must not be primes, so we mark them off as non-primes. Then we look at the next number, 3. Similarly,   | 
 | 64 | + * all multiples of 3 such as 3 × 2 = 6, 3 × 3 = 9, ... must not be primes, so we mark them off as well.   | 
 | 65 | + * Now we look at the next number, 4, which was already marked off. What does this tell you? Should you   | 
 | 66 | + * mark off all multiples of 4 as well?  | 
 | 67 | + *     | 
 | 68 | + * 4 is not a prime because it is divisible by 2, which means all multiples of 4 must also be divisible   | 
 | 69 | + * by 2 and were already marked off. So we can skip 4 immediately and go to the next number, 5. Now,   | 
 | 70 | + * all multiples of 5 such as 5 × 2 = 10, 5 × 3 = 15, 5 × 4 = 20, 5 × 5 = 25, ... can be marked off.   | 
 | 71 | + * There is a slight optimization here, we do not need to start from 5 × 2 = 10. Where should we start marking off?  | 
 | 72 | + *     | 
 | 73 | + * In fact, we can mark off multiples of 5 starting at 5 × 5 = 25, because 5 × 2 = 10 was already marked off   | 
 | 74 | + * by multiple of 2, similarly 5 × 3 = 15 was already marked off by multiple of 3. Therefore, if the current   | 
 | 75 | + * number is p, we can always mark off multiples of p starting at p2, then in increments of p: p2 + p, p2 + 2p, ...   | 
 | 76 | + * Now what should be the terminating loop condition?  | 
 | 77 | + *     | 
 | 78 | + * It is easy to say that the terminating loop condition is p n, which is certainly correct but not efficient.   | 
 | 79 | + * Do you still remember Hint #3?  | 
 | 80 | + *     | 
 | 81 | + * Yes, the terminating loop condition can be p n, as all non-primes ≥ √n must have already been marked off.   | 
 | 82 | + * When the loop terminates, all the numbers in the table that are non-marked are prime.  | 
 | 83 | + *   | 
 | 84 | + * The Sieve of Eratosthenes uses an extra O(n) memory and its runtime complexity is O(n log log n).   | 
 | 85 | + * For the more mathematically inclined readers, you can read more about its algorithm complexity on   | 
 | 86 | + * [Wikipedia](http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithm_complexity).  | 
 | 87 | + *   | 
 | 88 | + *	public int countPrimes(int n) {  | 
 | 89 | + *	   boolean[] isPrime = new boolean[n];  | 
 | 90 | + *	   for (int i = 2; i < n; i++) {  | 
 | 91 | + *	      isPrime[i] = true;  | 
 | 92 | + *	   }  | 
 | 93 | + *	   // Loop's ending condition is i * i < n instead of i < sqrt(n)  | 
 | 94 | + *	   // to avoid repeatedly calling an expensive function sqrt().  | 
 | 95 | + *	   for (int i = 2; i * i < n; i++) {  | 
 | 96 | + *	      if (!isPrime[i]) continue;  | 
 | 97 | + *	      for (int j = i * i; j < n; j += i) {  | 
 | 98 | + *	         isPrime[j] = false;  | 
 | 99 | + *	      }  | 
 | 100 | + *	   }  | 
 | 101 | + *	   int count = 0;  | 
 | 102 | + *	   for (int i = 2; i < n; i++) {  | 
 | 103 | + *	      if (isPrime[i]) count++;  | 
 | 104 | + *	   }  | 
 | 105 | + *	   return count;  | 
 | 106 | + *	}  | 
 | 107 | + *     | 
 | 108 | + *                 | 
 | 109 | + **********************************************************************************/  | 
 | 110 | + | 
 | 111 | +#include <stdlib.h>  | 
 | 112 | +#include <iostream>  | 
 | 113 | +#include <vector>  | 
 | 114 | +using namespace std;  | 
 | 115 | + | 
 | 116 | +int countPrimes(int n) {  | 
 | 117 | +    vector<bool> isPrimer(n, true);  | 
 | 118 | + | 
 | 119 | +    for(int i=2; i*i<n; i++){  | 
 | 120 | +        if (isPrimer[i]){  | 
 | 121 | +            for(int j=i*i; j<n; j+=i){  | 
 | 122 | +                isPrimer[j] = false;  | 
 | 123 | +            }  | 
 | 124 | +        }  | 
 | 125 | +    }  | 
 | 126 | + | 
 | 127 | +    int cnt = 0;  | 
 | 128 | +    for(int i=2; i<n; i++){  | 
 | 129 | +        if (isPrimer[i]) {   | 
 | 130 | +            //cout << i << ", ";  | 
 | 131 | +            cnt++;  | 
 | 132 | +        }  | 
 | 133 | +    }  | 
 | 134 | +    return cnt;  | 
 | 135 | +}  | 
 | 136 | + | 
 | 137 | + | 
 | 138 | +int main(int argc, char**argv)   | 
 | 139 | +{  | 
 | 140 | +    int n = 100;  | 
 | 141 | +    if (argc>1){  | 
 | 142 | +        n = atoi(argv[1]);  | 
 | 143 | +    }  | 
 | 144 | +    | 
 | 145 | +    cout << endl << n << " : " << countPrimes(n) << endl;  | 
 | 146 | + | 
 | 147 | +    return 0;  | 
 | 148 | +}  | 
0 commit comments