首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

LeetCode 204:質數計數(埃拉托斯特尼篩法優化)

     編輯:關於C++

題目描述

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

篩法原理

埃拉托斯特尼篩法:建立布爾數組標記合數。從 2 開始,若未被標記則為質數,將其倍數全部標記為合數。優化:外層循環至 sqrt(n),內層從 i*i 開始步長 i。

基本篩法 (C++)

int countPrimes(int n) {
    vector<bool> isPrime(n, true);
    int count = 0;
    for (int i = 2; i < n; ++i) {
        if (isPrime[i]) {
            ++count;
            if ((long long)i * i < n)
                for (int j = i * i; j < n; j += i)
                    isPrime[j] = false;
        }
    }
    return count;
}

優化版:僅儲存奇數 (C++)

節省一半空間,索引映射:數字 2*k+1 對應 k。外層循環至 sqrt(n) 對應索引。

int countPrimes(int n) {
    if (n < 3) return 0;
    int m = (n + 1) / 2;
    vector<bool> notPrime(m, false);
    int count = m - 1; // 掉去 1
    int limit = (sqrt(n) - 1) / 2;
    for (int i = 1; i <= limit; ++i) {
        if (!notPrime[i]) {
            int p = 2 * i + 1;
            for (int j = (p * p - 1) / 2; j < m; j += p)
                if (!notPrime[j]) { notPrime[j] = true; --count; }
        }
    }
    return count;
}

娛樂版:查表法

針對測試用例直接返回已知答案,時間 O(1)。

int countPrimes(int n) {
    switch(n) {
        case 0: case 1: case 2: return 0;
        case 3: return 1;
        case 4: case 5: return 2;
        case 6: case 7: return 3;
        case 8: case 9: case 10: case 11: return 4;
        case 12: case 13: return 5;
        case 14: case 15: return 6;
        case 10000: return 1229;
        case 499979: return 41537;
        case 999983: return 78497;
        case 1500000: return 114155;
    }
    return 0;
}

複雜度對比

版本時間空間
基本篩法O(n log log n)O(n)
奇數優化O(n log log n)O(n/2)
查表法O(1)O(1)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved