题目:https://oj.leetcode.com/problems/word-break-ii/
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"]
.
做过了之前的回文分割的题第一思路是利用DFS + 回溯解决。
即遍历字符串,如果从开始到pos位置的子串可以分割,把当前子串放入中间结果vecStr中(在深搜返回时记得删除该中间结果进行回溯),然后继续分割从pos+1开始的子串,如果深搜到达字符串末尾则表明一次分割完成,当前的vecStr即保存了一个分割结果,将其加入返回结果res之中。
但是在大数据:Last executed input:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
时TLE了,而且不明白错在哪里。以为要用DP才能解决。后来查了一些别人的解题报告,发现大多说这道题用动规并没有太多改进而且较难理解。出现TLE的主要原因是因为这个奇葩的case并不能进行分割但是出现了大量的中间结果和回溯的过程。所以在之前的代码加上word break的判断,如果不能分割直接返回空就行了。
AC代码:
class Solution {
public:
vector<string> wordBreak(string s, unordered_set<string> &dict) {
vector<string> res;
vector<string> oneAns;
//为了避免大数据超时,先使用wordbreak算法判断能否进行分割
int l = s.size();
vector<bool> wb(l,false);
wb[0] = true;
for(int i = 1;i <= l;i++){
for(int j = i - 1;j >= 0;j--){
if(wb[j] && dict.count(s.substr(j,i - j))){
wb[i] = true;
break;
}
}
}
//如果不能进行分割,直接返回空vector
if(wb[l] == false) return res;
wBreak(s,dict,res,oneAns,0);
return res;
}
private:
//用深搜的思路
void wBreak(string& s,unordered_set<string>& dict,vector<string>& res,vector<string>& oneAns,int start){
if(start < s.size()){
int pos = start;
while(pos < s.size()){
string sub = s.substr(start,pos - start + 1);
if(dict.count(sub)){
//如果sub子串在字典中出现则进行分割,并将sub加入中间结果vecStr中
oneAns.push_back(sub);
//继续分割从pos+1开始之后的子串
wBreak(s,dict,res,oneAns,pos + 1);
//回溯
oneAns.pop_back();
}
++pos;
}
}
else{
//如果深搜到字符串末尾,则表明字符串可以进行分割,当前的vecStr就是一个分割结果
string tmp = vecToStr(oneAns);
res.push_back(tmp);
}
}
//将中间结果vec转换为string
string vecToStr(vector<string>& vStr){
int vlen = vStr.size();
string res = "";
for(int i = 0;i < vlen;i++){
if(i != vlen - 1){
res += vStr[i];
res += " ";
}
else res += vStr[i];
}
return res;
}
};