1、爬楼梯
1.1 题目
1.2 题解
1.3 代码
1.3.1 递归
递归更容易相当和理解,但leetcode会超时
java
class Solution {
// 思路:基于递归实现,第n级的次数,等于第n-1和第n-2级次数之和
public int climbStairs(int n) {
// 第1级有1种方法
if (n == 1) {
return 1;
}
// 第2级有2种方法
if (n == 2) {
return 2;
}
// 第n级就是n-1级的方法 + n-2级的方法
return climbStairs(n-1) + climbStairs(n-2);
}
}
1.3.2 动态规划
思路:
动态规划,数组存储每个台阶的方法
遍历数组,i - 1加i - 2即是当前台阶的方法,全部存到相应的数组
最后result[n]就是n级台阶的方法
java
class Solution {
// 思路:基于动态规划
public int climbStairs(int n) {
// 处理边界条件
if (n == 1) {
return 1;
}
// 用数组记录n个台阶的方法数,其中跳过了索引0
int[] result = new int[n + 1];
// 台阶数为1是1种方法
result[1] = 1;
// 台阶数为2是2种方法
result[2] = 2;
// 台阶数为3时遍历到最后
for (int i = 3; i <= n; i++) {
// 那i阶就等于i-1 加 i-2时的和
result[i] = result[i - 1] + result[i -2];
}
// 最后返回n阶台阶即是结果
return result[n];
}
}
2、杨辉三角
2.1 题目
2.2 题解
2.3 代码
Dynamic programming
dp:
定义状态 dpi][j] 为杨辉三角中第 i 行第 j 列(行列索引从 0 开始)的元素值。
状态转移方程为:dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j],其中 dp[i - 1][j - 1] 和 dp[i - 1][j] 是当前元素左上方和上方的元素值。
需要注意的是,每一行的第一个元素和最后一个元素都是 1,即当 j=0 或 j=i 时,dp[i][j] = 1。
java
class Solution {
// 思路:基于动态规划,
// 状态转移方程 dp[i][j] = dp[i-1]dp[j-1] + dp[i-1]dp[j]
// 每一行的第一个和最后一个元素都是1
public List<List<Integer>> generate(int numRows) {
// 初始化动态规划数组,一行数组长度就是1
Integer[][] dp = new Integer[numRows][];
// 遍历每一行
for (int i = 0; i < numRows; i++) {
// 初始化当前行,因为从0开始的,所以当前行数组长度应为 i + 1
dp[i] = new Integer[i + 1];
// 每一行的第一个元素为1
dp[i][0] = 1;
// 每一行的最后一个元素为1 array.length -1 = (i + 1) - 1
dp[i][i] = 1;
// 计算中间元素(取出收尾都是1)
for (int j = 1; j < i; j++) {
// 套用公式中间元素等于上一行的相邻两个元素之和
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
}
}
// 将动态规划数组转换为结果列表
List<List<Integer>> result = new ArrayList<>();
for (Integer[] nums : dp) {
result.add(Arrays.asList(nums));
}
// 返回结果列表
return result;
}
}
3、打家劫舍
3.1 题目
3.2 题解
3.3 代码
基于动态规划,如果房子为1,直接偷了就算了
如果房子为2,那的看下哪一个大偷了就是了
如果大于2,如果第i个房子要偷,最大值就是前i-2加上i的和,否则不偷就是
第i-1个的和,就有公式了 dp[i] = Math.max((dp[i-2] + nums[i]), dp[i-1])
java
class Solution {
public int rob(int[] nums) {
// 思路:动态规划
// 处理边界,为空直接是0
if (nums == null ||nums.length == 0) {
return 0;
}
// 如果房子为1,直接偷了就是了
if (nums.length == 1) {
return nums[0];
}
// 如果房子为2,那得看看哪一个多偷了就是了
if (nums.length == 2) {
return Math.max(nums[0], nums[1]);
}
// 构造动态规划数组
int[] dp = new int[nums.length];
// 赋初始值
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
// 如果房子大于2,就有公式了 dp[i] = Math.max((dp[i-2] + nums[i]), dp[i-1])
for (int i = 2; i < nums.length; i++) {
dp[i] = Math.max((dp[i - 2] + nums[i]), dp[i - 1]);
}
// 最后返回数组最后的位置
return dp[nums.length - 1];
}
}
4、完全平方数
4.1 题目
4.2 题解
4.3 代码
java
class Solution {
public int numSquares(int n) {
// 定义一个动态规划数组 n = 13 = 9 + 4
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
int minn = Integer.MAX_VALUE;
for (int j = 1; j * j <= i; j++) {
// 使用 j*j作为完全平方数的一部分,查找剩余 i-j*j的数量
minn = Math.min(minn, dp[i - j * j]);
}
// 将minn + 1赋值给dp[i],加1表示使用了一个j*j平方
dp[i] = minn + 1;
System.out.println(dp[i]);
}
// 最后返回dp[n]
return dp[n];
}
}