题目描述:
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]
示例 2:
输入:
s = “pineapplepenapple”
wordDict = [“apple”, “pen”, “applepen”, “pine”, “pineapple”]
输出:
[
“pine apple pen apple”,
“pineapple pen apple”,
“pine applepen apple”
]
解释: 注意你可以重复使用字典中的单词。
示例 3:
输入:
s = “catsandog”
wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出:
[]
方法1:
主要思路:
(1)使用unordered_map<string,vector> 存储之前出现过的字符串对应的可能的所有的组成,这样来避免重复计算出现过的字符串的可能的组成结果,实现剪枝;
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_map<string,vector<string>> mp;//存储出现过的字符串对应的字符串分割组合
return helper(mp,wordDict,s);
}
vector<string> helper(unordered_map<string,vector<string>>& mp,vector<string>&wordDict,string s){
if(mp.count(s)){//若当前字符串之前分割过,则直接返回之前分割的结果
return mp[s];
}
//若要分割的字符串的长度为0,则直接返回空字符串
if(s.empty()){
return {""};
}
vector<string> res;//存储返回结果
//对每个单词的可能分割进行遍历
for(string& word:wordDict){
//若当前单词不能分割字符串,则处理下一个单词
if(s.substr(0,word.size())!=word){
continue;
}
//将当前单词后面的字符串接着进行分割
vector<string> tmp_res=helper(mp,wordDict,s.substr(word.size()));
//将后面的字符串的分割结果和当前单词进行组合
for(string&tmp:tmp_res){
if(tmp.empty()){//空字符串时,直接压入当前单词即可
res.push_back(word);
}
else{//否则,将当前单词和分割结果进行组合
res.push_back(word+" "+tmp);
}
}
}
//将当前字符串的分割结果进行统计
mp[s]=res;
return res;//返回当前字符串的统计结果
}
};