零钱兑换 II LeetCode 518
题目链接:[LeetCode 518 - 中等]
思路
完全背包类问题:
①遍历顺序:先遍历物品后遍历背包
②初始化:dp[0]=1;
③与题意相关的问题:dp[j]+=dp[j-coins[i]];
动态规划:
class Solution {
public int change(int amount, int[] coins) {
int[] dp =new int[amount+1];
dp[0]=1;
for(int i=0;i<coins.length;i++){
for(int j=coins[i];j<=amount;j++){
dp[j]+=dp[j-coins[i]];
}
}
return dp[amount];
}
}
组合总和 Ⅳ LeetCode 377
题目链接:[LeetCode 377 - 中等]
思路
排列&组合类问题遍历的顺序不同
排列问题:先遍历物品后遍历背包
组合问题:先遍历背包后遍历物品
动态规划:
class Solution {
public int combinationSum4(int[] nums, int target) {
int[] dp = new int[target+1];
dp[0]=1;
for(int j=0;j<=target;j++){
for(int i=0;i<nums.length;i++){
if(j >= nums[i]){
dp[j] += dp[j - nums[i]];
}
}
}
return dp[target];
}
}
爬楼梯 LeetCode 70
题目链接:[LeetCode 70 - 简单]
思路
与#377基本一致
动态规划:
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n+1];
dp[0]=1;
int[] b={1,2};
for(int j=0;j<=n;j++){
for(int i=0;i<b.length;i++){
if(j>=b[i]){
dp[j]+=dp[j-b[i]];
}
}
}
return dp[n];
}
}
进阶版
import java.util.Scanner;
class climbStairs{
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
int m, n;
while (sc.hasNextInt()) {
// 从键盘输入参数,中间用空格隔开
n = sc.nextInt();
m = sc.nextInt();
// 求排列问题,先遍历背包再遍历物品
int[] dp = new int[n + 1];
dp[0] = 1;
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= m; i++) {
if (j - i >= 0) dp[j] += dp[j - i];
}
}
System.out.println(dp[n]);
}
}
}
零钱兑换 LeetCode 332
题目链接:[LeetCode 332 - 中等]
思路
与#518思路相似,但是需要解决:
如果coins中的硬币不能够满足amount的金额要求:if(dp[j-coins[i]]!=max)
动态规划:
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
int max = Integer.MAX_VALUE;
for(int i=1;i<=amount;i++){
dp[i]=max;
}
for(int i=0;i<coins.length;i++){
for(int j=coins[i];j<=amount;j++){
if(dp[j-coins[i]]!=max){
dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
}
}
}
return dp[amount]==max?-1:dp[amount];
}
}
完全平方数 LeetCode 279
题目链接:[LeetCode 279 - 中等]
思路
该题为排列问题(完全背包问题):
遍历顺序:先遍历物品后遍历背包
动态规划:
class Solution {
public int numSquares(int n) {
int[] dp = new int[n+1];
int max = Integer.MAX_VALUE;
for(int i=1;i<=n;i++){
dp[i]=max;
}
dp[0]=0;
for(int i=1;i*i<=n;i++){
for(int j=i*i;j<=n;j++){
dp[j]=Math.min(dp[j],dp[j-i*i]+1);
}
}
return dp[n];
}
}
单词拆分 LeetCode 139
题目链接:[LeetCode 139 - 中等]
思路
较难,多刷(看卡哥视频)
动态规划:
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> set = new HashSet(wordDict);
boolean[] valid = new boolean[s.length()+1];
valid[0]=true;
for(int i=0;i<=s.length();i++){
for(int j=0;j<i&&!valid[i];j++){
if(set.contains(s.substring(j,i))&&valid[j]){
valid[i]=true;
}
}
}
return valid[s.length()];
}
}