140. 单词拆分 II
正向dfs(TLE)
class Solution {
public:
vector<string> res;
unordered_set<string> st;
vector<string> wordBreak(string s, vector<string> &wordDict) {
for (auto s:wordDict)st.insert(s);
vector<string> path;
dfs(s, 0, path);
return res;
}
void dfs(const string &s, int u, vector<string> path) {
if (u == s.size()) {
string tmp;
for (int i = 0; i < path.size(); i++) {
if (i)tmp += " ";
tmp += path[i];
}
res.push_back(tmp);
return ;
}
for (int i = u; i < s.size(); i++) {
auto prefix = s.substr(u, i - u + 1);
if (st.count(prefix)) {
path.push_back(prefix);
dfs(s, i + 1, path);
path.pop_back();
}
}
}
};
TLE的问题所在:
比如这个样例:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
计算过["cat","sand","dog"]后,实际上从catsand后面的已经计算过了。
在计算到["cats","and"]的时候,实际上跟计算到["cat","sand"]后面的情况是一模一样的,但是又重复计算了一遍,造成了超时。
反向dfs(记忆化)
很巧妙的记忆化QAQ
class Solution {
public:
unordered_map<int, vector<string>> res;
unordered_set<string> wordSet;
vector<string> wordBreak(string s, vector<string> &wordDict) {
for (auto s:wordDict)wordSet.insert(s);
dfs(s, 0);
return res[0];
}
void dfs(const string &s, int index) {
if (res.count(index)) return;
if (index == s.size()) {
res[index] = {""};
return;
}
// res[index] = {};
for (int i = index + 1; i <= s.size(); ++i) {
string word = s.substr(index, i - index);
if (wordSet.count(word)) {
dfs(s, i);
for (const string &str: res[i]) {
res[index].push_back(str.empty() ? word : word + " " + str);
}
}
}
}
};
网友评论