|  | 
|  | 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