auto commit
This commit is contained in:
parent
111e9d45de
commit
5d4376eb77
|
@ -410,18 +410,48 @@ public int pop() throws Exception {
|
|||
|
||||
## 题目描述
|
||||
|
||||
以 O(1) 的时间复杂度求菲波那切数列。
|
||||
求菲波那契数列的第 n 项。
|
||||
|
||||
<div align="center"><img src="https://latex.codecogs.com/gif.latex?f(n)=\left\{\begin{array}{rcl}0&&{n=0}\\1&&{n=1}\\f(n-1)+f(n-2)&&{n>1}\end{array}\right."/></div> <br>
|
||||
|
||||
## 解题思路
|
||||
|
||||
如果使用递归求解,那么会重复计算一些子问题。例如,求 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) 被重复计算了。
|
||||
|
||||
<div align="center"> <img src="../pics//955af054-8872-4569-82e7-2e10b66bc38e.png" width="300"/> </div><br>
|
||||
|
||||
递归方法是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,避免重复求解子问题。
|
||||
|
||||
```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. 旋转数组的最小数字
|
||||
|
||||
## 题目描述
|
||||
|
|
Loading…
Reference in New Issue
Block a user