LeetCode:70. 爬楼梯 - 力扣(LeetCode)
1.思路
思路一:找规律。当前台阶走法是前两个台阶走法之和。台阶数小于2时,直接返回对应数值,台阶数大于等于3时,采用滚动的方式获取前两个台阶方式之和,返回结果即可。
思路二:动态规划。在上述找规律的基础上建立起来的推导逻辑。初始化时需要简单注意一下边界。
2.代码实现
// 方法一洗洗脑
class Solution {
public int climbStairs(int n) {
int a = 1, b = 2, c = 0;
if (n <= 2) {
return n;
}
for (int i = 3; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return c;
}
}
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
// dp[2] = 2;
for (int i = 2; i < n + 1; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).
LeetCode:322. 零钱兑换 - 力扣(LeetCode)
1.思路
理解题意,从coins[]数组中获取物品填进容量为amount的背包中是否有值存在?存在的话返回最小值。
2.代码实现
class Solution {
public int coinChange(int[] coins, int amount) {
// 动规
int[] dp = new int[amount + 1]; // 初始化容量为最大值
for (int i = 0; i < dp.length; i++) {
dp[i] = Integer.MAX_VALUE; // 求最小值,故应该把对应默认值都初始化为int的最大值
}
dp[0] = 0;
// 遍历推导
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j <= amount; j++) {
if (dp[j - coins[i]] != Integer.MAX_VALUE) { // 当前一个值为int的最大值时是无效的
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
}
3.复杂度分析
时间复杂度:O(n^2).
空间复杂度:O(n).
LeetCode:
1.思路
理解题意:将完全平方数塞入容量为n的背包,最少需要几个完全平方数。完全平方数为物品,n为背包。注:一定可以装满,全用1装,也是最大值。
2.代码实现
class Solution {
public int numSquares(int n) {
// 动规
int[] dp = new int[n + 1];
// 求最小值,先声明为最大值
for (int i = 0; i <= n; i++) {
dp[i] = Integer.MAX_VALUE;
}
dp[0] = 0;
// 遍历 + 推导
for (int i = 1; i * i <= n; i++) { // 遍历完全平方数 i^2
for (int j = i * i; j <= n; j++) { // 遍历背包
// if (dp[j - i ^ 2] != Integer.MAX_VALUE) {
dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
// }
}
}
return dp[n];
}
}
3.复杂度分析
时间复杂度:O(n ^ 2).
空间复杂度:O(n).