[题目描述]Given a string s and a dictionary of wordsdict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog"
,
dict = ["cat", "cats", "and", "sand", "dog"]
.
A solution is ["cats and dog", "cat sand dog"]
.
解答:本题目要求找出一个字符串中所有可能的切分方式,使得每个切分的单词都在字典中。
常见的解决此类问题的方法当然是dfs。但是,这样会带来效率低下的问题。举一个简单的例子。
a | a | a | a | a | ... | a | a | a | a | a |
如果字典为dict = {"a","aa","aaa",...}。
下面看看这样带来的重复搜索的代价。
比如第一个"a"在字典中,那么我们需要搜索余下的序列s[1,...,size]。但是,在递归的过程中会出现重复搜索。比如,在搜索第一个"a"的递归过程中搜索了s[2,...,size]的字符串的切分结果,但是在第一个为"aa"时,又要重复搜索这个字符串的切分结果。下面给出一个树形结构。
为了避免重复,当然最好是将已经得到的结果保存起来,避免重复搜索带来的效率低下。下面给出代码:
class Solution {
public:
map < string, vector<string> >record;
vector<string> wordBreak(string s, unordered_set<string> &dict) {
vector<string> result;
int size = s.size();
for (int i = 1; i <= size; i++){
string word = s.substr(0, i);
if (dict.count(word)){
if (i == size){
result.push_back(word);
}
else{
string remain = s.substr(i, size - i);
vector<string> remainSet;
if (record.count(remain) == 0){
remainSet = wordBreak(remain, dict);
}
else{
remainSet = record[remain];
}
int num = remainSet.size();
for (int i = 0; i < num; i++){
result.push_back(word + " " + remainSet[i]);
}
}
}
}
record[s] = result;
return result;
}
};