代码随想录刷题记录 day41 单词拆分+背包总结
参考:代码随想录
139. 单词拆分
思想
-
dp[i] 字符串长度为i,若dp[i]==true,表示可以拆分为一个或多个在字典中出现的单词
-
递推公式
如果dp[j]=true,[j,i]这个区间的子串出现在字典里,dp[i]一定是true。
if([j,i]这个区间的子穿出现在字典里 && dp[j]是true) dp[i]=true
3.初始化 dp[0]=true,其他的都为false
-
遍历顺序
排列问题 先遍历背包,在遍历物品
-
dp数组打印
代码
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
//dp[i] 字符串长度为i,若dp[i]==true,表示可以拆分为一个或多个在字典中出现的单词
//递推公式
//如果dp[j]=true,[j,i]这个区间的子串出现在字典里,dp[i]一定是true。
// if([j,i]这个区间的子穿出现在字典里 && dp[j]是true) dp[i]=true
//3.初始化 dp[0]=true,其他的都为false
HashSet<String> set=new HashSet<>(wordDict);
boolean[] valid=new boolean[s.length()+1];
valid[0]=true;
//4.遍历顺序
//排列问题 先遍历背包,在遍历物品
for(int i=1;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()];
}
}
背包总结
动态规划五部曲
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- 初始化
- 遍历顺序
- dp数组打印
对于递推公式和遍历顺序是有一定的规律的。
-
递推公式
-
能否装满背包,或者说最多能装多少
dp[j]=max(dp[j-nums[i]]+nums[i],dp[j]);
dp[j]表示背包容量为j,最多能装dp[j]的物品
题目:
416. 分割等和子集
1049. 最后一块石头的重量 II
-
装满有几种方法
dp[j]+=dp[j-nums[i]]
dp[j]表示容量为j的背包,装满有dp[j]种方法
题目:
494. 目标和
518. 零钱兑换 II
377. 组合总和 Ⅳ
70. 爬楼梯
-
装满背包所需物品的最小的个数
dp[j]=min(dp[j-coins[i]]+1,dp[j])
题目
322. 零钱兑换
279. 完全平方数
-
-
遍历顺序
-
01背包
二维数组遍历顺序都是可以的,第二次for循环是从小到大遍历
一维数组只能先遍历物品,再遍历背包,且第二次for循环从大到小遍历。
-
完全背包
第二层从小到大遍历
组合问题:先遍历物品再遍历背包。 518. 零钱兑换 II
排列问题:先遍历背包,再遍历物品。377. 组合总和 Ⅳ 70. 爬楼梯
求最小数:两次for循环都是可以的 322. 零钱兑换 [279. 完全平方数](
-