每次求解子串s的解集时,单独定义一个ans看上去可读性更好,但是试了一下不用ans直接更新mem_,反而速度更快!
(我的程序写法更简洁,比huahua的程序简洁一些)
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.cbegin(), wordDict.cend());
return wordBreak(s, dict);
}
private:
unordered_map<string, vector<string>> mem_; //用mem_记忆每一段string对应的所有分割解
vector<string> wordBreak(string& s, unordered_set<string>& dict) {
//检查当前字符串是否被计算过, 如果计算过就直接返回之前得到的解集
if(mem_.count(s)) return mem_[s];
//当前子串 s 的解集
vector<string> ans;
//先检查整个字符(子)串是否在字典里, 如果在就直接作为当前s的一种解放入对应的mem_的value中
//if(dict.count(s)) mem_[s].push_back(s);
if(dict.count(s))
mem_[s].push_back(s);
//现在开始从左往右逐个扫描分割点, 探索每一种可能的解并保存到哈希表
//能不能直接保存到哈希表? 还是要到最后一起放进去:最后一起放进去在逻辑上更清晰,...,直接mem_[s].push_back的话,mem_中原来没有s,也不会报错,也可以
for(int i=1; i<s.length(); i++) {
string left = s.substr(0, i);
string right = s.substr(i);
if(dict.count(right)) {
vector<string> temp = wordBreak(left, dict);
if(!temp.empty()) { //左边子串的break结果数组不为空,至少有一种结果
for(int i=0; i<temp.size(); i++) {
mem_[s].push_back(temp[i]+" "+right);
}
}
}
}
//当前的s子串所有解查找完毕,更新到缓存中
//mem_[s] = ans;
return mem_[s];
}
};