题目描述
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
- 分隔时可以重复使用字典中的单词。
- 你可以假设字典中没有重复的单词。
示例:
输入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出:
[
"cats and dog",
"cat sand dog"
]
解题思路
先做139题。会做139题就行,这个题有点难了,可战略性放弃。只是看着大佬题解,转成C++代码通过了,回溯(dfs)部分并是不很理解。
参考代码
class Solution {
public:
vector<string> wordBreak(string str, vector<string>& wordDict) {
int length = str.length();
unordered_set<string> word_set(wordDict.begin(), wordDict.end());
bool dp[length];
memset(dp, 0, sizeof(dp));
string tmp; // 必须这么写,uset.count("" + str[0])这么写不可以!
tmp += str[0];
if(word_set.count(tmp) > 0)
dp[0] = true;
for(int i = 1; i < length; i++){
if(word_set.count(str.substr(0, i+1)) > 0){
dp[i] = true;
continue;
}
for(int j = 0; j < i; j++){
if(dp[j] && word_set.count(str.substr(j+1, i-j)) > 0){
dp[i] = true;
break;
}
}
}
// 以上是139题的代码,直接套用。
vector<string> res;
if(dp[length - 1]){
deque<string> path;
dfs(str, length-1, word_set, res, path, dp);
}
return res;
}
// 回溯
void dfs(string &str, int curEnd, unordered_set<string> &word_set, vector<string> &res, deque<string> &path, bool* dp){
string prefix = str.substr(0, curEnd+1);
if(word_set.count(prefix) > 0){
path.push_front(prefix);
string tmp = "";
for(auto s: path)
tmp += (s + " ");
tmp = tmp.substr(0, tmp.size() - 1);
res.push_back(tmp);
path.pop_front();
}
for(int i = 0; i < curEnd; i++){
if(dp[i]){
string suffix = str.substr(i+1, curEnd-i);
if(word_set.count(suffix) > 0){
path.push_front(suffix);
dfs(str, i, word_set, res, path, dp);
path.pop_front();
}
}
}
}
};
探讨了如何利用字典中的单词对给定字符串进行有效拆分,形成合法句子的所有可能性。介绍了使用回溯算法(DFS)解决此问题的思路与实现过程。
663

被折叠的 条评论
为什么被折叠?



