Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
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"]
.
Thanks to:https://discuss.leetcode.com/topic/12997/11ms-c-solution-concise
不能理解自己为什么反复TLE…
可能是数据又被加强了吧…
这道题可以用2维的区间DP去做,令DP[i][j]表示i~j为回文,则d[i][j]=dp[i][k] & dp[k+1][j]
然后发现其实这样是没有必要的,因为set查询复杂度是O(1),所以求取dp[i][k]的复杂度并不高,所以不需要另开一维。
于是一维就够了,dp[i]表示0~i是否是想要的字符串;
两重循环就可以做出,类似上一题,然后进行递归获取全解。。。
然而就是这样一直TLE…
究其原因可能是DP+回溯用了太多时间,
而参考的方法直接存储了子元素的解…这样成功地阻止了对某一解的反复求取…
很强。。。佩服
他是从后往前求取值,生成一个前缀数组,每次加上后缀。
这样仅仅通过递归即可解决。
使用了map来存储一个字符串的解,很强…
class Solution {
public:
unordered_map<string, vector<string>> m;
vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
//找出一个字符串已经存在的匹配vector
if(m.count(s)) return m[s];
int n=s.size();
vector<string> result;
if(wordDict.find(s)!=wordDict.end())
result.push_back(s);
for(int i=1;i<n;i++){
string suffix=s.substr(i);
if(wordDict.count(suffix)){
//取前一部分字符串
string temp=s.substr(0,i);
vector<string> suffpre=merge(suffix,wordBreak(temp,wordDict));
result.insert(result.end(),suffpre.begin(),suffpre.end());
}
}
m[s]=result;
return result;
}
//添加后缀
vector<string> merge(string suffix,vector<string> pre){
for(int i=0;i<pre.size();i++){
pre[i]+=" "+suffix;
}
return pre;
}
};
自己的方法虽然超时,但是还是贴一下供之后自己查阅
//这个方法依然会超时
// int n;
// string s;
// unordered_set<string> wordDict;
// bool dp[1000][1000];
// int n=s.size();
// this->n=n;
// this->s=s;
// this->wordDict=wordDict;
// vector<string> result;
// //所以昨天一开始自己的直觉的对的,是区间DP,而上一题所用应当是压缩一维之后的
// // bool dp[n][n];
// memset(dp,0,sizeof(dp));
// for(int len=1;len<=n;len++){
// for(int i=0;i<n && len+i-1<n;i++){
// int j=len+i-1;
// //获取当前对应的子字符串
// dp[i][j]=wordDict.find(s.substr(i,j-i+1))!=wordDict.end();
// // //判断dp[i][j]和 dp[i][k] & dp[k+1][j]
// // for(int k=i;k<j && !dp[i][j];k++){
// // dp[i][j]=dp[i][k] && dp[k+1][j];
// // }
// }
// }
// //得到dp矩阵
// // for(int i=0;i<n;i++){
// // for(int j=0;j<n;j++){
// // printf("%d ",dp[i][j]);
// // }
// // printf("\n");
// // }
// // printf("\n");
// //dp[0][n-1]为所求解
// string temp="";
// generate(temp,n-1,result);
// return result;
// void generate(string temp,int start,vector<string> &result){
// if(start==n){
// result.push_back(temp);
// return;
// }
// for(int i=0;i<=start;i++){
// if(dp[i][start]){
// string pre=temp;
// if(temp==""){
// temp=s.substr(i,start-i+1);
// generate(temp,i-1,result);
// }
// else{
// temp=temp+" "+s.substr(i,start-i+1);
// generate(temp,i-1,result);
// }
// // temp=pre;
// }
// }
// }
//超时
// void generate(vector<string> &temp,int start,int size,vector<string> &result){
// if(start==n){
// //将temp里的元素汇集成一个string推到result里
// string final="";
// for(int i=0;i<temp.size();i++){
// if(i==0) final=temp[i];
// else final=final+" "+temp[i];
// }
// result.push_back(final);
// return;
// }
// for(int i=start;i<n;i++){
// //这个位置可以构成解
// if(dp[i+1]){
// string t=s.substr(start,i-start+1);
// //首先t必须在字典里
// if(wordDict.find(t)==wordDict.end()) continue;
// //size表示temp数组里元素的总长
// //要求当前到达的总长必须为遍历到的串总长
// if(size+t.size()==i+1){
// temp.push_back(t);
// generate(temp,i+1,i+1,result);
// temp.pop_back();
// }
// }
// }
// }