思路
先考虑朴素做法,也就是枚举所有的子串,时间复杂度为$O(kn^3)$,$k$为词表大小,$n$为s的长度。
接下来考虑怎么优化,由于朴素枚举是每次遍历一个可能的方案。考虑能否每次遍历一类方案,也就是利用DP或者递推的思路。
集合表示: f[i]
是一个布尔变量,它表示$S_1$-$S_i$是否能拆分成词表中的单词。
集合计算: f[i] = f[i - j] && S[j]-S[i]在词表中
时间复杂度$O(n^2)$,这里要做到$O(n^2)$必须保证查找字符串是否在词表中这一步的复杂度为$O(1)$,因此不能用库函数自带的哈希表(因为计算一个字符串的哈希值需要遍历一遍这个字符串,那么复杂度为$O(n)$),只能手写字符串哈希(因为在这个问题下可以优化)。
至于第二题,直接DFS找方案即可。
伪$O(n^2)$做法,实际上是$O(n^3)$
class Solution {
public:
unordered_set<string> S;
bool wordBreak(string s, vector<string>& wordDict) {
for(auto &word : wordDict) S.insert(word);
int n = s.size();
vector<bool> f(n + 1);
s = ' ' + s;
f[0] = true;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {
if(S.count(s.substr(j, i - j + 1)) && f[j - 1]) // 每次需要计算substr的哈希值,是线性的时间复杂度
f[i] = true;
}
}
return f[n];
}
};
手写哈希做法,真$O(n^2)$
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
typedef unsigned long long ULL; // 相当于定义了模2^64下的加法运算,自带取模
const int p = 131; // p是经验值,一般取131,或者13331
unordered_set<ULL> S;
for(auto &word : wordDict) {
ULL h = 0;
for(auto c: word) h = h * p + c;
S.insert(h);
}
int n = s.size();
vector<bool> f(n + 1);
s = ' ' + s;
f[0] = true;
for(int i = 0; i <= n; i++) {
if(f[i]) {
ULL h = 0;
for(int j = i + 1; j <= n; j++) { // 改变一下遍历顺序,方便计算哈希值
h = h * p + s[j]; // 注意这里是常数时间就得到了哈希值
if(S.count(h)) f[j] = true;
}
}
}
return f[n];
}
};
单词拆分II
class Solution {
public:
typedef unsigned long long ULL;
const int P = 131;
vector<string> ans;
unordered_set<ULL> S;
vector<string> wordBreak(string s, vector<string>& wordDict) {
for(auto & word: wordDict){
ULL h = 0;
for(auto c: word) h = h * P + c;
S.insert(h);
}
dfs(s, 0, "");
return ans;
}
void dfs(string& s, int u, string path) {
if(u == s.size()) {
path.pop_back();
ans.push_back(path);
return;
}
ULL h = 0;
for(int i = u; i < s.size(); i++) {
h = h * P + s[i];
if(S.count(h)) { // 如果u-i这一段子串在词表中,则继续dfs
dfs(s, i + 1, path + s.substr(u, i - u + 1) + " ");
}
}
}
};
- Post link: https://scnujackychen.github.io/2021/03/22/LC-139/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub IssuesGitHub Discussions