问题描述:https://leetcode-cn.com/problems/word-break-ii/description/
给定一个非空字符串 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"]
输出:
[]
思路:在刚才找出是否存在的基础上,再输出。关键是标记已经找到的。
class Solution {
public:
vector<string> res[1000];
vector<string> lres;
bool find(string s, vector<string>& wordDict,int j,int i)
{
string t=s.substr(j,i-j+1);
for(int k=0;k<wordDict.size();k++)
{
if(t==wordDict[k])
{
res[i].push_back(t);
return true;
}
}
return false;
}
vector<string> wordBreak(string s, vector<string>& wordDict)
{
int N=s.length();
if(N==0) return lres;
bool a[1000];
a[0]=find(s,wordDict,0,0);
for(int i=1;i<N;i++)
{
a[i]=false;
for(int j=0;j<i;j++)
{
if(a[j]&&find(s,wordDict,j+1,i)) //[j+1,i]
{
a[i]=true;
}
}
if(find(s,wordDict,0,i))
{
a[i]=true;
}
}
for(int i=0;i<res[N-1].size();i++)
{
dfs(N-1-res[N-1][i].length(),res[N-1][i]);
}
return lres;
}
void dfs(int k,string s)
{
if(k==-1)
lres.push_back(s);
else
{
for(int i=0;i<res[k].size();i++)
{
dfs(k-res[k][i].length(),res[k][i]+" "+s);
}
}
}
};
回溯法,超时
class Solution {
public:
int n;
vector<string> ones,res;
void dfs(int idex,vector<string>& wordDict,string s)
{
if(idex==n)
{
string ss="";
for(int i=0;i<ones.size();i++)
ss+=(ones[i]+" ");
res.push_back(ss.substr(0,ss.length()-1));
return;
}
else
{
for(int i=0;i<wordDict.size();i++)
{
if(wordDict[i]==s.substr(idex,wordDict[i].length()))
{
ones.push_back(wordDict[i]);
dfs(idex+wordDict[i].length(),wordDict,s);
ones.pop_back();
}
}
}
}
vector<string> wordBreak(string s, vector<string>& wordDict) {
n=s.length();
if(n==0) return {};
dfs(0,wordDict,s);
return res;
}
};