139. 单词拆分
✅做题思路or感想
看得出来是动态规划,但想了半天解不出来。。。。
可以转化为背包问题中的是否能把背包装满的问题,因为词典里的词可以重复用,所以这是一个完全背包
dp数组含义
dp[i]
表示长度为i
的字符串能不能被被分解(其实就是容量为i
的背包能否被装满)
💡递推公式
设wordSize
是遍历到的词典单词的大小
如果下标[0, i - 1]
的字符串已经被匹配了,即dp[i] = true
,并且后面的大小为wordSize
的子串在词典中出现过,则有dp[i + wordSize] = true
得匹配
这里的思路和往常的由dp[i - 1]
推dp[i]
不同,这里是通过dp[i]
去推导dp[i + wordSize]
初始化
因为为了推导递推公式,所以dp[0] = true
,为了推导公式而生
但其实理解也很好理解:长度为0的字符串(空字符串)不需要字典中的单词也可以拼出来 ,无为而治之
遍历顺序
因为这里是完全背包,所以遍历背包是正序
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
//dp[i],长度为i的子串能不能由字典拼凑,true or false
vector<bool>dp (s.size() + 1, false);
dp[0] = true;
for (int i = 0; i < s.size(); i++) {
for (string &word : wordDict) {
int wordSize = word.size();
if (i + wordSize > s.size())continue;
if (dp[i] && s.substr(i, wordSize) == word)dp[i + wordSize] = true;
}
}
return dp[s.size()];
}
};