diff --git a/notes/剑指 offer 题解.md b/notes/剑指 offer 题解.md
index bb7dc781..8af879a1 100644
--- a/notes/剑指 offer 题解.md
+++ b/notes/剑指 offer 题解.md
@@ -410,18 +410,48 @@ public int pop() throws Exception {
## 题目描述
-以 O(1) 的时间复杂度求菲波那切数列。
+求菲波那契数列的第 n 项。
## 解题思路
-如果使用递归求解,那么会重复计算一些子问题。例如,求 f(10) 需要计算 f(9) 和 f(8),计算 f(9) 需要计算 f(8) 和 f(7),可以看到 f(8) 被重复计算了。
+如果使用递归求解,会重复计算一些子问题。例如,计算 f(10) 需要计算 f(9) 和 f(8),计算 f(9) 需要计算 f(8) 和 f(7),可以看到 f(8) 被重复计算了。
递归方法是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,避免重复求解子问题。
+```java
+public int Fibonacci(int n) {
+ if(n <= 1) return n;
+ int[] fib = new int[n + 1];
+ fib[1] = 1;
+ for (int i = 2; i <= n; i++) {
+ fib[i] = fib[i - 1] + fib[i - 2];
+ }
+ return fib[n];
+}
+```
+
+考虑到第 i 项只与第 i-1 和第 i-2 项有关,因此只需要存储前两项的值就能求解第 i 项,从而将空间复杂度由 O(N) 降低为 O(1)。
+
+```java
+public int Fibonacci(int n) {
+ if(n <= 1) return n;
+ int pre2 = 0, pre1 = 1;
+ int fib = 0;
+ for (int i = 2; i <= n; i++) {
+ fib = pre2 + pre1;
+ pre2 = pre1;
+ pre1 = fib;
+ }
+ return fib;
+}
+```
+
+由于待求解的 n 小于 40,因此可以将前 40 项的结果先进行计算,之后就能以 O(1) 时间复杂度得到第 n 项的值了。
+
```java
public class Solution {
private int[] fib = new int[40];
@@ -446,6 +476,8 @@ public class Solution {
## 解题思路
+复杂度:O(N) + O(N)
+
```java
public int JumpFloor(int n) {
if (n == 1) return 1;
@@ -459,6 +491,22 @@ public int JumpFloor(int n) {
}
```
+复杂度:O(N) + O(1)
+
+```java
+public int JumpFloor(int n) {
+ if (n <= 1) return n;
+ int pre2 = 0, pre1 = 1;
+ int result = 0;
+ for (int i = 1; i <= n; i++) {
+ result = pre2 + pre1;
+ pre2 = pre1;
+ pre1 = result;
+ }
+ return result;
+}
+```
+
# 10.3 变态跳台阶
## 题目描述
@@ -488,9 +536,11 @@ public int JumpFloorII(int n) {
## 解题思路
+复杂度:O(N) + O(N)
+
```java
public int RectCover(int n) {
- if (n < 2) return n;
+ if (n <= 2) return n;
int[] dp = new int[n];
dp[0] = 1;
dp[1] = 2;
@@ -501,6 +551,22 @@ public int RectCover(int n) {
}
```
+复杂度:O(N) + O(1)
+
+```java
+public int RectCover(int n) {
+ if (n <= 2) return n;
+ int pre2 = 1, pre1 = 2;
+ int result = 0;
+ for (int i = 3; i <= n; i++) {
+ result = pre2 + pre1;
+ pre2 = pre1;
+ pre1 = result;
+ }
+ return result;
+}
+```
+
# 11. 旋转数组的最小数字
## 题目描述