140. Word Break II
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. Return all such possible sentences.
Note:
The same word in the dictionary may be reused multiple times in the segmentation.
You may assume the dictionary does not contain duplicate words.
Example 1:
Input:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
Output:
[
"cats and dog",
"cat sand dog"
]
Example 2:
Input:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
Output:
[
"pine apple pen apple",
"pineapple pen apple",
"pine applepen apple"
]
Explanation: Note that you are allowed to reuse a dictionary word.
Example 3:
Input:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
Output:
[]
方法1:
huahua: https://www.youtube.com/watch?v=JqOIRBC0_9c
思路:
和139. Word Break 一样的思路,不一样的是这里要用hash把递归解全部记下来,与上一层合并。在helper里,首先要剪枝所有查询并记录过的结果,如果找到了立刻返回。否则开始递归。递归过程中首先建立一个新的ans来暂时保存所有当前s的解集。1. 要查整个s是否在dict里,是的话先推入,2. 左边分割出1个,2个,… size() - 1个字符,一次查询右边是否inDict,如果没有可以立刻结束本循环尝试下一种分割。而如果有,需要开始递归解左边。如果假设左边的所有解被返回装进了left_ans,那么当前s的解集包括所有string s: left_ans + right的组合,i.e. 个数由左边解集大小决定,同时这样也包括了左边不可解的情况,因为自动返回空集。append是一个util函数,用来完成这一步追加。注意,此时不能终止循环,因为查询所有解,必须将所有分割点尝试一遍才能最终送入hash,否则解不完整且重复多次被送入。
Complexity
Time complexity: O(2^n)
Space complexity: O(2^n)
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
return breakHelper(s, wordSet);
}
private:
unordered_map<string, vector<string> > hash;
void append(vector<string> & left_ans, string & right){
for (string & s: left_ans){
s += " " + right;
}
}
vector<string> breakHelper(string & s, unordered_set<string> & wordSet){
if (hash.count(s)) return hash[s];
vector<string> ans;
if (wordSet.count(s)) ans.push_back(s);
for (int i = 1; i < s.size(); i++){
string left = s.substr(0, i);
string right = s.substr(i);
if (wordSet.count(right)) {
vector<string> left_ans = breakHelper(left, wordSet);
append(left_ans, right);
ans.insert(ans.end(), left_ans.begin(), left_ans.end());
}
}
hash[s] = ans;
return hash[s];
}
};