WordBreak
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode"
,
dict = ["leet", "code"]
.
Return true because "leetcode"
can be segmented as "leet code"
.
方法一,深搜(超时):
class Solution {
public:
bool check(string s1,string s2){
if(s2.length() > s1.length() || s1.substr(0,s2.length()) != s2)
return false;
else
return true;
}
typedef unordered_set<string>::iterator iter;
bool found = false;
bool wordBreak(string s, unordered_set<string> &dict) {
if(s==""){
found = true;
return true;
}
for(iter it = dict.begin();it != dict.end();it++)
{
if(found) return true;
if(check(s,*it)){
int l = (*it).length();
if(wordBreak(s.substr(l,s.length() - l), dict)){
return true;
}
}
}
return false;
}
};
方法二,动态规划:
设f[i]代表用s[0]-s[i]的字符串是否能拼起来,则状态转移方程
f[i] = any(f[j] && s[j+1,i] ∈dict) (-1 <= j < i)
时间复杂度O(n^2)
class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int l = s.length();
bool *f = (bool*)calloc(l,sizeof(bool));
for(auto x:dict)
if(x == s.substr(0,x.length())){
f[x.length() - 1] = true;
}
for(int i = 0; i < l; i++){
if(f[i]) continue;
for(int j = 0; j < i; j++){
if(f[j] && dict.find(s.substr(j+1,i-j)) != dict.end()){
f[i] = true;
break;
}
}
}
bool ans = f[l - 1];
delete f;
return ans;
}
};
WordBreak 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"]
.
分析:
比上题多了输出所有方案,只要在dp的过程中记一下中间结果即可。
g[i]表示s[g[i]+1,i]是dict里面的单词,在dp结束后,从S.length()-1位置可以往回一次找到每次划分出的单词。
注意到g[i]可能会有多种答案,g[i]所以是一个集合,g是元素为集合的数组。
class Solution {
public:
vector<string> ans;
string ss;
vector<string> wordBreak(string s, unordered_set<string> &dict) {
ss = s;
int l = s.length();
bool *f = (bool*)calloc(l,sizeof(bool));
vector<unordered_set<int> > g(l);
for(auto x:dict)
if(x == s.substr(0,x.length())){
f[x.length() - 1] = true;
g[x.length() - 1].insert(-1);
}
for(int i = 0; i < l; i++){
for(int j = 0; j < i; j++){
if(f[j] && dict.find(s.substr(j+1,i-j)) != dict.end()){
f[i] = true;
g[i].insert(j);
}
}
}
string now = "";
trace_ans(l-1,g,now);
delete f;
return ans;
}
void trace_ans(int i,vector<unordered_set<int> > g,string now){
if(i == -1){
ans.push_back(now.substr(0,now.length() - 1));
return;
}
for(auto x:g[i])
trace_ans(x, g, ss.substr(x+1, i-x) + " " + now);
}
};