leetCode(49):Count Primes
Description:
Count the number of prime numbers less than a non-negative number, n.
推斷一個數是否是質數主要有下面幾種方法:
1)直接用該數除於全部小於它的數(非0。1),假設均不能被它整除,則其是質數。
2)除以小於它一半的數。由於大於其一半必然是無法整除。假設均不能被它整除。則其是質數;
3)除以小於sqrt(a)的數,原因例如以下:
除了sqrt(a)之外,其它的兩數乘積為a的,一定是比個比sqrt(a)小,一個比sqrt(a)大。所以推斷到sqrt(a)就能夠了,由於還有一半就是剛才做除法的商的那部份。
4)除以小於sqrt(a)的質數就可以。
由於質數不能被除自身和1外的全部數整除。非質數則不然,且其必定能被某一質數整除。假設一個數能被某一非質數整除。則其必定能被組成這一非質數的最小質數整數。
從上能夠看出,推斷一個數是否是質數。其計算量取決於整除的個數。上述四種方法,除數逐漸變少。
通過以上分析,這是本人自己的程序:
class Solution { public: int countPrimes(int n) { if (n == 0 || n == 1 || n==2) return 0; vector<int> vec;//質數容器 vec.push_back(2); for (int i = 3; i < n; ++i) { int j = 0; int length=vec.size(); for (; j<length && vec[j]*vec[j]<i; ++j)//除數是小於sqrt(i)的全部質數 { if (i%vec[j] == 0) break; } if (vec[j]*vec[j]>i) vec.push_back(i); } return vec.size(); } };
以下是在網上找到一個程序,非常具體:
這道題給定一個非負數n,讓我們求小於n的質數的個數,題目中給了充足的提示。解題方法就在第二個提示埃拉托斯特尼篩法Sieve of Eratosthenes中。這個算法的步驟例如以下圖所看到的,我們從2開始遍歷到根號n,先找到第一個質數2,然後將其全部的倍數全部標記出來。然後到下一個質數3。標記其全部倍數。一次類推,直到根號n,此時數組中未被標記的數字就是質數。我們須要一個n-1長度的bool型數組來記錄每一個數字是否被標記,長度為n-1的原因是題目說是小於n的質數個數。並不包含n。
然後我們用兩個for循環來實現埃拉托斯特尼篩法,難度並非非常大。代碼例如以下所看到的:
class Solution { public: int countPrimes(int n) { vector<bool> num(n - 1, true); num[0] = false; int res = 0, limit = sqrt(n); for (int i = 2; i <= limit; ++i) { if (num[i - 1]) { for (int j = i * i; j < n; j += i) {//為什麽要從i*i開始,由於小於i*i的數可能已經被小於i的數整除了。假設沒有,那它就是質數 num[j - 1] = false; } } } for (int j = 0; j < n - 1; ++j) { if (num[j]) ++res; } return res; } };
leetCode(49):Count Primes