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

演算法逐步推導(二):階乘尾部零計數 — 從暴力模擬到對數時間數學解法

     編輯:關於C

題目

給定 n,求 n! (階乘) 十進制表示中尾部連續 0 的個數。

方法一:暴力模擬 (教學用,不可用於大 n)

邏輯:建立陣列 [1, 2, ..., n],反覆尋找因子 2 與 5 配對 (因為 10=2×5),計數配對次數。


// 概念碼,n>20 即溢位,n>10^5 記憶體/時間不可行
int count = 0;
int *arr = malloc(n * sizeof(int));
for (i=0;i

複雜度:O(n²) 時間、O(n) 空間。僅適合極小 n 驗證邏輯。

方法二:數學公式法 (標準解,O(log n))

核心洞見:階乘中因子 2 的個數遠多於 5,**尾部零個數 = 因子 5 的總個數**。

每 5 個數貢獻 1 個 5,每 25 個數額外貢獻 1 個 (25=5²),每 125 個再額外 1 個...

公式:

zeros(n) = ⌊n/5⌋ + ⌊n/25⌋ + ⌊n/125⌋ + ... = Σ ⌊n/5ᵏ⌋

O(log₅ n) 程式碼


long long trailingZeros(long long n) {
    long long count = 0;
    for (long long p = 5; p <= n; p *= 5) {
        count += n / p;
        if (p > n / 5) break;  // 防止 p*=5 溢位
    }
    return count;
}

驗證範例

nn!尾部零公式計算
512015/5=1
103628800210/5=2
25...625/5 + 25/25 = 5+1=6
100...2420+4=24
1000...249200+40+8+1=249

延伸:任意進制尾部零

若求 n! 在 base B 下尾部零:

  1. 分解 B = p₁ᵉ¹ × p₂ᵉ² × ... (質因數分解)。
  2. 對每個質因數 pᵢ,計算 n! 中 pᵢ 的指數 expᵢ = Σ ⌊n/pᵢᵏ⌋。
  3. 答案 = min(⌊expᵢ / eᵢ⌋)。

複雜度比較

方法時間空間最大可行 n
暴力模擬O(n²)O(n)~20 (溢位前)
大整數乘法 + 計數O(n log n)O(n log n)~10⁵
數學公式 (推薦)O(log n)O(1)10¹⁸+ (64位整數)

核心思維:不要模擬過程,要分析本質。尾部零本質是質因數 2 與 5 的配對,而 2 過剩,故只需數 5。這種「質因數分解視角」是解決大數組合數學問題的萬能鑰匙。

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