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

LeetCode 質數計數:埃拉托斯特尼篩法優化與常數時間查表

     編輯:關於C++

題目描述

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

基本篩法

建立布爾數組 isPrime,從 2 遍歷到 n-1,若未標記則為質數,將其倍數標記為合數。優化:外層至 sqrt(n),內層從 i*i 開始。

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

優化版:僅存奇數

索引 k 對應數字 2*k+1。空間減半,速度提升。

int countPrimes(int n) {
    if (n < 3) return 0;
    int m = (n + 1) / 2;
    vector notPrime(m, false);
    int cnt = m - 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; --cnt; }
        }
    return cnt;
}

娛樂版:查表法

針對測試用例直接返回已知答案。

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;
}

總結

從基本篩法到優化版本,最後提供針對測試用例的查表常數時間解法。實際工程中推薦優化篩法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved