1. 程式人生 > >leetCode(49):Count Primes

leetCode(49):Count Primes

size rgb con bool padding blog scrip 技術分享 res

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