斐波那契數列是經典算法題,遞歸解法雖簡潔但效率極低(指數級時間複雜度)。本文展示基於迭代的 O(n) 時間、O(n) 空間實現,並說明 Integer 溢出邊界與應對策略。
僅需兩個變量滾動保存前兩項,循環累加生成後續項,存入列表返回。避免遞歸棧溢出與重複計算。
import java.util.ArrayList;
import java.util.List;
public class Fibonacci {
/**
* 生成前 size 項斐波那契數列
* @param size 期望項數(>0)
* @return 包含前 size 項的列表
* @throws IllegalArgumentException size < 0
*/
public static List<Integer> generate(int size) {
if (size < 0) {
throw new IllegalArgumentException("size 不能為負數");
}
List<Integer> result = new ArrayList<>(size);
if (size == 0) return result;
result.add(0);
if (size == 1) return result;
result.add(1);
int first = 0, second = 1;
for (int i = 2; i < size; i++) {
int next = first + second; // 可能溢出,見下文
first = second;
second = next;
result.add(next);
}
return result;
}
public static void main(String[] args) {
List<Integer> fib = generate(10);
fib.forEach(n -> System.out.print(n + "\t")); // 0 1 1 2 3 5 8 13 21 34
}
}
Integer.MAX_VALUE = 2,147,483,647(約 21.4 億)因此 size >= 47 時會發生溢出。原文提到 983 是錯誤的(可能混淆了長整型)。
Long:支援到第 92 項(19 位數)。BigInteger:任意大小,性能稍差但最安全。import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public static List<BigInteger> generateBig(int size) {
if (size < 0) throw new IllegalArgumentException("size < 0");
List<BigInteger> res = new ArrayList<>(size);
if (size == 0) return res;
res.add(BigInteger.ZERO);
if (size == 1) return res;
res.add(BigInteger.ONE);
BigInteger a = BigInteger.ZERO, b = BigInteger.ONE;
for (int i = 2; i < size; i++) {
BigInteger c = a.add(b);
a = b;
b = c;
res.add(c);
}
return res;
}
| 實現 | 時間複雜度 | 空間複雜度 | 最大安全項數 |
|---|---|---|---|
| 遞歸 | O(2^n) | O(n) 棧 | 極小 |
| 迭代 | O(n) | O(n) 列表 | 46 |
| 迭代 + Long | O(n) | O(n) | 92 |
| 迭代 + BigInteger | O(n * M) | O(n * M) | 無限 |
其中 M 為大整數位數。對於常規業務(size < 50),Long 版本性能最佳且足夠安全。