140. Word Break II
缓存的重要性:
方法一:直接dfs,TLE
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.begin(), wordDict.end());
vector<string> res;
helper(s, 0, dict, "", res);
return res;
}
private:
void helper(string& s, int idx, unordered_set<string>& dict, string temp, vector<string>& res) {
if (idx == s.size()) {
res.push_back(temp.substr(0, temp.size()-1));
return;
}
for (int i = idx; i < s.size(); ++i) {
string str = s.substr(idx, i-idx+1);
if (dict.find(str) != dict.end())
helper(s, i+1, dict, temp+str+" ", res);
}
}
};
方法二:缓存,16ms
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.begin(), wordDict.end());
unordered_map<int, vector<string>> m;
auto res = helper(s, 0, dict, m);
for (auto& str : res)
str = str.substr(0, str.size()-1);
return res;
}
private:
vector<string> helper(string& s, int idx, unordered_set<string>& dict, unordered_map<int, vector<string>>& m) {
//m存的是s中某个位置向后的所能够组成的string的集合
if (idx == s.size())
return vector<string>{string("")};//最后这个必须要有,不然最后一个结果都没有
if (m.find(idx) != m.end())
return m[idx];
vector<string> res;
for (int i = idx; i < s.size(); ++i) {
string str = s.substr(idx, i-idx+1);
if (dict.find(str) != dict.end()) {
auto nextStrs = helper(s, i+1, dict, m);
for (auto& nextStr : nextStrs)
res.push_back(str + " " + nextStr);
}
}
m[idx] = res;
return res;
}
};
//必须要缓存中间结果,不然超时
//可以缓存的不一定是dp
所以缓存不是一定得在dp上用,其他为了提高效率也可以用