diff --git a/algorithm/03-data-structure.md b/algorithm/03-data-structure.md index 2669320..7d1d311 100644 --- a/algorithm/03-data-structure.md +++ b/algorithm/03-data-structure.md @@ -284,3 +284,95 @@ function searchRotated(nums, target) { return -1; } ``` + +--- + +## 7. 斐波那契数列 + +> **场景**:算法入门经典题、理解递归与动态规划思想、缓存优化演示、爬楼梯问题变种。 +> **解决**:求第 n 位斐波那契数(F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2))。 + +### 方法一:普通递归(不推荐) + +```js +// 时间复杂度 O(2^n),存在大量重复计算 +function fib(n) { + if (n <= 1) return n; + return fib(n - 1) + fib(n - 2); +} +``` + +### 方法二:记忆化递归 + +```js +// 时间复杂度 O(n),空间复杂度 O(n) +function fib(n, memo = {}) { + if (n <= 1) return n; + if (memo[n]) return memo[n]; + return memo[n] = fib(n - 1, memo) + fib(n - 2, memo); +} +``` + +### 方法三:动态规划 + +```js +// 时间复杂度 O(n),空间复杂度 O(n) +function fib(n) { + if (n <= 1) return n; + const dp = [0, 1]; + for (let i = 2; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; +} +``` + +### 方法四:空间优化(推荐) + +```js +// 时间复杂度 O(n),空间复杂度 O(1) +function fib(n) { + if (n <= 1) return n; + let prev = 0, curr = 1; + for (let i = 2; i <= n; i++) { + [prev, curr] = [curr, prev + curr]; + } + return curr; +} +``` + +### 方法五:矩阵快速幂(大数优化) + +```js +// 时间复杂度 O(log n),适合求极大位数 +function fib(n) { + if (n <= 1) return n; + + const multiply = (a, b) => [ + [a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]], + [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]] + ]; + + const power = (m, p) => { + let result = [[1, 0], [0, 1]]; // 单位矩阵 + while (p > 0) { + if (p & 1) result = multiply(result, m); + m = multiply(m, m); + p >>= 1; + } + return result; + }; + + const matrix = [[1, 1], [1, 0]]; + return power(matrix, n - 1)[0][0]; +} +``` + +| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | +|------|-----------|-----------|----------| +| 普通递归 | O(2^n) | O(n) | 仅理解思想 | +| 记忆化递归 | O(n) | O(n) | 面试常考 | +| 动态规划 | O(n) | O(n) | 面试常考 | +| 空间优化 | O(n) | O(1) | **推荐** | +| 矩阵快速幂 | O(log n) | O(1) | 大数/竞赛 | +