题目:
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"
.
题目来源:https://oj.leetcode.com/problems/word-break/
解题思路:dfs超时,从第一个字母开始,不断增加字母查看是否在字典中,如果是,接着从下一个字符开始查找,时间复杂度是O(2^n),计算:F(n)=F(n-1)+F(n-2)+……+F(1),F(1)=1,则F(2)=1,F(3)=2,F(4)=4……F(n)=2^(n-2).
由于可以进行深搜,有可能具有动归实现的可能性,考虑用动归。动归:用f[i]表示s[0,i)是否可分割,true表示可以,false表示不可以,则f[i]=f[j] &&s[j,i)在字典中,这样就可以用动归来解了。
注意:当一个问题可以用深搜来解,且超时,则可以考虑用动态规划来解。
#include<iostream>
#include<string>
#include<vector>
#include<unordered_set>
using namespace std;
bool wordBreak(string s,int first,int last,unordered_set<string> &dict)
{
if(dict.find(string(s.begin()+first,s.end()))!=dict.end())
return true;
for(int i=first;i<last;i++)
{
if(dict.find(string(s.begin()+first,s.begin()+i+1))!=dict.end() && wordBreak(s,i+1,last,dict))
return true;
}
return false;
}
bool wordBreak(string s, unordered_set<string> &dict)
{
return wordBreak(s,0,s.size()-1,dict);
}
bool wordBreak1(string s, unordered_set<string> &dict)
{
vector<bool> f(s.size()+1,false);//f[i]表示s[0,i)可分
f[0]=true;//0个字符可以分割
for(int i=1;i<=s.size();i++)
{
for(int j=i-1;j>=0;j--)
{
if(f[j] && dict.find(s.substr(j,i-j))!=dict.end())
{
f[i]=true;
break;
}
}
}
return f[s.size()];
}
int main()
{
unordered_set<string> dict;
dict.insert("aa");
dict.insert("aaaa");
string s="aaaaaa";
cout<<wordBreak1(s,dict)<<endl;
system("pause");
return 0;
}