Note:
就是看看怎么个拆分法能给拆成让单词都出现在字典里面
状态表示:f[i]
表示0 ~ i
是否可以被拆分
状态转移方程:f[i] = f[i - 1] & i ~ j是否出现在字典里面
为了能保证查询子串是否出现在字典里面,使用字符串hash操作来实现O(1)的复杂度
这样就要尽量去保证从前往后的去计算字符串哈希
所以在递推每种状态的时候,就倒着推
初始化f[n] = true
这是说当你前面找到第一个符合标准的划分方法之后就可以划分了,最后是空的字符,不会有影响的
代码如下:
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
typedef unsigned long long ULL;
unordered_set<ULL> hash;
const int P = 131;
for(auto& word: wordDict){
ULL h = 0;
for(auto c: word) h = h * P + c;
hash.insert(h);
}
int n = s.size();
vector<bool> f(n + 1);
f[n] = true;
for(int i = n - 1; i >= 0; i --){
ULL h = 0;
for(int j = i; j < n; j ++){
h = h * P + s[j];
if(hash.count(h) && f[j + 1]){
f[i] = true;
break;
}
}
}
return f[0];
}
};