问题描述
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. You may assume the dictionary does not contain duplicate words.
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"]
.
算法分析
1、从字符串开始处分析,如果第一个单词是cat
,则该组剩余的单词是在sanddog
里提取,即sand
和dog
;
2、如果第一个单词是cats
,则该组剩余的单词在在anddog
里提取,即and
和dog
;
3、很明显这是一个递归问题,找出一个单词后递归查找剩余的单词。
4、使用一个unsorted_map<string, vector<string>>
数据结构存储每一次递归查找一个字符串的结果。查找"cat"
的结果为["cat"]
;查找"cats"
的结果为["cats"]
;查找"catsand"
的结果为["cat sand", "cats and"]
;查找"catsanddog"
的结果为["cat sand dog", "cats and dog"]
。
C++实现
class Solution {
private:
unordered_map<string, vector<string>> m;
vector<string> combine(string word, vector<string> prev) {
for(int i = 0; i < prev.size();++i)
prev[i] += " " + word;
return prev;
}
bool isaWord(string s, vector<string>& wordDict) {
vector<string>::iterator it = find(wordDict.begin(), wordDict.end(), s);
return (it != wordDict.end());
}
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
if (m.count(s))
return m[s]; //take from memory
vector<string> result;
if (isaWord(s, wordDict)) //a whole string is a word
result.push_back(s);
for(int i = 1;i < s.size(); ++i) {
string word = s.substr(i);
if(isaWord(word, wordDict)) {
string rem = s.substr(0, i);
vector<string> prev = combine(word, wordBreak(rem, wordDict));
result.insert(result.end(), prev.begin(), prev.end());
}
}
m[s] = result; //memorize
return result;
}
};