力扣509题、70题(斐波那契数列、爬楼梯)
509、斐波那契数列
基本思想:
动态规划,滚动数组思想
具体实现:
动态递归五部:
1.确定dp数组以及下标的含义
dp[i]的定义为:第i个数的斐波那契数值是dp[i]
2.确定递推公式
状态转移方程dp[i] = dp[i - 1] + dp[i - 2]
3.dp数组如何初始化
dp[0] = 0;
dp[1] = 1;
4.确定遍历顺序
从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],
那么遍历的顺序一定是从前到后遍历的
5.举例推导dp数组
n为10的dp数组
0 1 1 2 3 5 8 13 21 34 55
代码:
class Solution { public int fib(int n) { if (n <= 1) return n; int[] dp = new int[n+1]; dp[0] = 0; dp[1] = 1; for (int index = 2; index <= n; index++){ dp[index] = dp[index - 1] + dp[index -2]; } return dp[n]; } }
![](https://img2020.cnblogs.com/blog/1940467/202103/1940467-20210310111304718-1626582477.png)
class Solution { public int fib(int n) { if (n < 2) return n; int p = 0, q = 1, r = 0; for (int i = 1; i < n; i++) { r = p + q; p = q; q = r; } return r; } }
70、爬楼梯
基本思想:
动态规划
具体实现:
1、确定dp数组及其含义
dp[i]:爬到第i层楼梯,有dp[i]种方法
2、确定递推公式
dp[i-1],上i-1层楼梯,有dp[i-1]种方法,再一步跳一个台阶就是dp[i]
dp[i-2],上i-2层楼梯,有dp[i-2]种方法,再一步跳两个台阶就是dp[i]
dp[i] = dp[i-1]+dp[i-2]
3、dp数组如何初始化
dp[1] = 1,dp[2] = 2,从i=3开始递推
4、确定遍历顺序
从递推公式看出,遍历顺序是从前往后
5、举例推导dp数组
n=5的时候
代码:
class Solution { public int climbStairs(int n) { int[] dp = new int[n + 1]; if (n <= 1) return n; dp[1] = 1; dp[2] = 2; for (int i = 3; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; } }
优化:
class Solution { public int climbStairs(int n) { if (n <= 1) return n; int[] dp = new int[3]; dp[1] = 1; dp[2] = 2; for (int i = 3; i <= n; i++) { int sum = dp[1] + dp[2]; dp[1] = dp[2]; dp[2] = sum; } return dp[2]; } }
牛客69 把数字翻译成字符串
- 当前字符不等于0的时候,dp[i] = dp[i-1],此时将当前位置的一个字符译码,类似于跳一个台阶
- 当前字符+前一个字符,记为num, 如果
10<=num<=26
此时符合两个合并一起译码的条件;类似于跳两个台阶- 若此时i等于1,直接dp[i]++;
- 大于1, 则dp[i] += dp[i-2];
- 举个例子: nums = "324"
- 此时dp[0] = 1, dp[1]呢? dp[2]呢?
- 很明显nums[1] != '0',所以dp[1] = dp[0],num = 32,此时不满足两个一起译码的条件则循环往下执行,此时 nums[2] != '0',则 dp[2] = dp[1] = 1, num = 24,此时满足两个一起译码的条件,因为i==2大于1,所以dp[2] += dp[2-2] ,dp[2] = 1+1 = 2。
import java.util.*; public class Solution { /** * 解码 * @param nums string字符串 数字串 * @return int整型 */ public int solve (String nums) { if(nums.length() == 0 || nums.charAt(0) == '0') return 0; int[] dp = new int[nums.length()]; dp[0] = 1; for (int i = 1; i < dp.length; i++) { if (nums.charAt(i) != '0') { dp[i] = dp[i - 1]; } int num = (nums.charAt(i - 1) - '0' )* 10 + (nums.charAt(i) - '0'); if (num >= 10 && num <= 26) { if (i == 1) dp[i] += 1; else dp[i] += dp[i - 2]; } } return dp[nums.length() - 1]; } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步