Word Break 系列
Word Break 系列
给定字符串和一个字典,问字符串手否能够能够被字典中的词完美组合出来
解法一:DP[i] 表示串从起始位置到 i 位置都能够用词典中的词构成,向前推进即可
// author: Tecker Yu
// time: 8ms
bool wordBreak(string s, vector<string>& wordDict) {
int len = s.size();
vector<int> dp(len+1, 0);
unordered_set<string> dict(wordDict.begin(), wordDict.end());
dp[0]=1;
for(int i=1;i<=len;++i) {
for(int j=i;j<=len;++j) {
if (dp[i-1] && dict.find(s.substr(i-1, j-i+1))!=dict.end()) dp[j]=1;
}
}
return dp[len];
}解法二:dp[i] 表示最长能够到达的位置+1
bool wordBreak(string s, unordered_set<string> &dict) {
if(dict.size()==0) return false;
vector<bool> dp(s.size()+1,false);
dp[0]=true;
for(int i=1;i<=s.size();i++)
{
// 从后往前只要能被组合,就继续查看下一个 i
for(int j=i-1;j>=0;j--)
{
if(dp[j])
{
string word = s.substr(j,i-j);
if(dict.find(word)!= dict.end())
{
dp[i]=true;
break;
}
}
}
}
return dp[s.size()];
}求出所有的完美组合并用空格分隔开
解法:记忆化搜索
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.begin(), wordDict.end());
return break_word(s, dict);
}
vector<string> append(vector<string> & left, string& right) {
vector<string> res;
for(auto prefix : left) {
res.push_back(prefix + " " + right);
}
return res;
}
vector<string>& break_word(string s, unordered_set<string> &dict) {
if (mem.count(s)) return mem[s];
vector<string> res;
// 边界:s 在词典中
if (dict.count(s)) res.push_back(s);
// 遍历分割点
for(int i=1;i<s.size();++i) {
string right=s.substr(i);
if (!dict.count(right)) continue;
string left=s.substr(0, i);
// 递归求解左半边和右半边,再加上右边的词
vector<string> left_res = append(break_word(left, dict), right);
// 添加进当前的解中
res.insert(res.end(), left_res.begin(), left_res.end());
}
// 记忆化求得的解
mem[s]=res;
return mem[s];
}
private:
unordered_map<string, vector<string> > mem;
};#递归 #分治 #DP