LeetCode筆記:204. Count Primes

weixin_34107955發表於2017-11-22

問題:

Count the number of prime numbers less than a non-negative number, n.

大意:

計算小於非負數n的質數個數。

思路:

題目很簡短,就是個找質數的問題。

我們知道最簡單的質數就是2,3,5。。。那怎麼計算往後的質數呢?質數的定義是除了自己以外沒有任何因子,也就是不被任何數整除,也就是說,不會被這個數前面的任何質數和非質數整除,其實非質數也可以被質數整除,比如4被2整除,所以問題可以歸結為:沒遇到一個數,判斷它是否能被前面的某一個質數整除。

要達到這個條件,我們需要記錄在遍歷過程中遇到的質數,所以弄了一個陣列來記錄遇到過的質數,當然2、3、5是一開始就要放進來的,我們遍歷時也應該從2開始,因為0和1不是質數。然後沒遇到質數都記錄下來,同時遇到的每個數都去試一試能不能被前面的質數整除。

這種做法在數字不大的情況下是奏效的,但是當數字大了以後,就會超時了。還是先看程式碼吧。

程式碼(Java):

public class Solution {
    public int countPrimes(int n) {
        int result = 0;
        int num = 3;
        int[] prime = new int[n+3];
        prime[0] = 2;
        prime[1] = 3;
        prime[2] = 5;
        for (int i = 2; i < n; i++) {
            if (i < 6 && i != 4) result ++;
            boolean isPrime = true;
            for (int j = 0; j < num; j++) {
                if (i % prime[j] == 0) isPrime = false;
            }
            if (isPrime) {
                result++;
                prime[num] = i;
                num++;
            }
        }
        return result;
    }
}

他山之石:

public class Solution {
    public int countPrimes(int n) {
        int result = 0;
        boolean[] notPrime = new boolean[n];
        for (int i = 2; i < n; i++) {
            if (notPrime[i] == false) {
                result ++;
                for (int j = 2; j*i < n; j++) {
                    notPrime[j*i] = true;
                }
            }
        }
        return result;
    }
}

這裡其實還是那個思路,但是加快了速度,為什麼呢?因為只需要在每次遇到質數時,將其小於n的倍數都設為非質數,這樣就避免了每次遇到一個數都要用之前所有質數去除一遍,大大降低了時間複雜度。

合集:https://github.com/Cloudox/LeetCode-Record


檢視作者首頁

相關文章