目录
[1. 第N个泰波那契数](#1. 第N个泰波那契数)
[1.1 解题思路](#1.1 解题思路)
[1.2 代码实现](#1.2 代码实现)
[2. 三步问题](#2. 三步问题)
[2.1 解题思路](#2.1 解题思路)
[2.2 代码实现](#2.2 代码实现)
[3. 使用最小花费爬楼梯](#3. 使用最小花费爬楼梯)
[3.1 解题思路](#3.1 解题思路)
[3.2 代码实现](#3.2 代码实现)
[4. 解码方法](#4. 解码方法)
[4.1 解题思路](#4.1 解题思路)
[4.2 代码实现](#4.2 代码实现)
1. 第N个泰波那契数
1.1 解题思路
我们可以使用递归来解决这道题,但是递归中有重复的运算,给一个数找到这个数的泰波那锲数,这里我们可以利用动态规划设置一个dp数组来记录这些计算过的数,直接在数组里面找这些重复计算的结果。

1.2 代码实现
使用动态规划解决的代码:
java
class Solution {
public int tribonacci(int n) {
//1 创建dp表
//2 初始化dp表
//3 填表
//4 返回结果
//处理边界条件
if(n == 0) {
return 0;
}
if(n == 1 ||n == 2) {
return 1;
}
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
for(int i = 3; i <= n; i++) {
dp[i] = dp[i-1] + dp[i-2] + dp[i-3];
}
return dp[n];
}
}
对代码进行了空间优化:
java
class Solution {
public int tribonacci(int n) {
//处理边界情况
if(n == 0) {
return 0;
}
if(n == 1 || n == 2) return 1;
//空间优化
int a = 0, b = 1, c = 1, d = 0;
for(int i = 3; i <= n; i++) {
d = a + b + c;
a = b;
b = c;
c = d;
}
return d;
}
}
2. 三步问题
2.1 解题思路

2.2 代码实现
java
class Solution {
public int waysToStep(int n) {
int MOD = (int)1e9 + 7;
//处理边界条件
if(n == 1) return 1;
if(n == 2) return 2;
if(n == 3) return 4;
int[] dp = new int[n+1];
dp[1] = 1;
dp[2] = 2;
dp[3] = 4;
for(int i = 4; i <= n; i++) {
dp[i] = ((dp[i-1] + dp[i-2]) % MOD + dp[i-3]) % MOD;
}
return dp[n];
}
}
3. 使用最小花费爬楼梯
3.1 解题思路

3.2 代码实现
思路一:
java
class Solution {
public int minCostClimbingStairs(int[] cost) {
int len = cost.length;
int[] dp = new int[len + 1];
dp[0] = 0;
dp[1] = 0;
for(int i = 2; i < len + 1; i++) {
dp[i] = Math.min(dp[i-1] + cost[i-1],dp[i-2] + cost[i-2]);
}
return dp[len];
}
}
思路二:
java
class Solution {
public int minCostClimbingStairs(int[] cost) {
int n = cost.length;
int[] dp = new int[n + 1];
dp[n-1] = cost[n-1];
dp[n-2] = cost[n-2];
for(int i = n - 3; i >= 0; i--) {
dp[i] = Math.min(dp[i+1] + cost[i], dp[i+2] + cost[i]);
}
return Math.min(dp[0], dp[1]);
}
}
4. 解码方法
4.1 解题思路

4.2 代码实现
java
class Solution {
public int numDecodings(String s) {
char[] arr = s.toCharArray();
int n = arr.length;
int[] dp = new int[n];
if(arr[0] != '0') dp[0] = 1;
if(n == 1) return dp[0];
if(arr[1] != '0' && arr[0] != '0') dp[1] += 1;
int tmp = (arr[0] - '0') * 10 + (arr[1] - '0');
if(tmp >= 10 && tmp <= 26) dp[1] += 1;
int count = 0;
for(int i = 2; i < n; i++) {
if(arr[i] != '0') dp[i] += dp[i-1];
int sum = (arr[i-1] - '0') * 10 + (arr[i] - '0');
if(sum >= 10 && sum <= 26) dp[i] += dp[i-2];
}
return dp[n-1];
}
}
我们还可以对上面代码中的初始化代码进行优化,将dp数组大小扩大一位,将初始化原来dp[1]位置的值,放在循环里面,代码如下:
java
class Solution {
public int numDecodings(String s) {
char[] arr = s.toCharArray();
int n = arr.length;
int[] dp = new int[n + 1];
dp[0] = 1;
if(arr[0] != '0') dp[1] = 1;
for(int i = 2; i <= n; i++) {
if(arr[i - 1] != '0') dp[i] += dp[i-1];
int sum = (arr[i - 2] - '0') * 10 + (arr[i - 1] - '0');
if(sum >= 10 && sum <= 26) dp[i] += dp[i-2];
}
return dp[n];
}
}