Leetcode 204. 計數質數

1. 暴力搜索

1.1 思路

根據質數定義,用每一個大於1且小於它本身的整數進行取餘運算,如果沒有整除情況,則該數爲質數。

1.2 複雜度

  • 時間複雜度 O(n^2)
  • 空間複雜度 O(1)

1.3 代碼

class Solution {
    public int countPrimes(int n) {
        int count = 0;
        for (int i = 2; i < n; i++) {
            if (isPrime(i)) {
                count++;
            }
        }
        return count;
    }

    private boolean isPrime(int n) {
        for (int i = 2; i < n; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
}

2. 暴力搜索優化

2.1 思路

對正整數 nn,只需用 [2,n][2, √n] 之間的正整數進行取餘運算,如果沒有整除情況,則爲質數。

2.2 複雜度

  • 時間複雜度 O(n^2)
  • 空間複雜度 O(1)

2.3 代碼

class Solution {
    public int countPrimes(int n) {
        if (n < 3) {
            return 0;
        }
        
        int count = 1;
        for (int i = 3; i < n; i = i + 2) {
            if (isPrime(i)) {
                count++;
            }
        }
        return count;
    }

    private boolean isPrime(int n) {
        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
}

3. 厄拉多塞篩選

3.1 思路

對每一個大於1的正整數,如果將它所有的倍數(不包括它本身)排除,那麼剩下的必爲質數。

3.2 複雜度

  • 時間複雜度 O(n)
  • 空間複雜度 O(n)

3.3 代碼

class Solution {
    public int countPrimes(int n) {
        int count = 0;
        boolean[] flag = new boolean[n];
        for (int i = 2; i < n; i++) {
            if (!flag[i]) {
                count++;
                for (int j = i + i; j < n; j += i) {
                    flag[j] = true;
                }
            }
        }
        return count;
    }
}

4. 厄拉多塞篩選優化

4.1 思路

使用布爾數組標記是否爲質數時,每個數佔用四個字節。實際上,完全可以使用一個比特記錄邏輯值,即位圖法。

4.2 複雜度

  • 時間複雜度 O(n)
  • 空間複雜度 O(n)

4.3 代碼

class Solution {
    public int countPrimes(int n) {
        int count = 0;
        int[] flag = new int[n / 32 + 1];
        for (int i = 2; i < n; i++) {
            if ((flag[i / 32] & (1 << (i & 31))) == 0) {
                count++;
                for (int j = i + i; j < n; j += i) {
                    flag[j / 32] |= 1 << (j & 31);
                }
            }
        }
        return count;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章