139.单词拆分
题解:
本题依旧使用动态规划法,使用动态规划五部曲
1.确定dp数组以及下标含义
dp[i]:字符串长度为i,dp[i]为true,即可以拆分为一个或多个在字典中出现的单词
2.确定递推公式
当dp[j]为true,那么在往后推导都会成立,所以dp[i]一定就是true
3.dp数组初始化
在递推公式中可以看出。dp[i]状态是依靠dp[j]是否为true,如果dp[0]表示字符串为空那么就是有空字符串,但题目说的条件是非空,所以排除这种情况
4.确定遍历顺序
题目中说可以拆分一个或多个在字典出现的单词,是一个完全背包
所以对于完全背包两层for循环本身顺序并不重要
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品(强调顺序)
字符串的顺序并不能颠倒,讲究要有一定顺序,所以一定是求排列数即先遍历背包顺序,然后在遍历物品顺序
for (int j = 0; j < wordDict.size(); j++) {//物品(非空字符串s)
for (int i = wordDict[j].size(); i <= s.size(); i++) //背包 (非空单词列表)
5.打印dp数组验证递推公式正确
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
vector<bool> dp(s.size() + 1, flase);
dp[0] = true;//dp数组初始化
//先遍历背包后遍历物品
for(int i = 1; i <= s.size(); i++) {
for (int j = 0; j < i; j++) {
string word = s.substr(j, i - j);//substr字符截取函数
if (wordSet.find(word) != wordSet.end() && dp[j]) {
dp[i] = true;
}
}
}
retur dp[s.size()];