Word Break
问题描述:给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。拆分时可以重复使用字典中的单词,并假设字典中没有重复的单词。
问题解决:一开始我打算用BFS来做,先找出字典中的第一个能够与字符串s的子串匹配的单词,然后用递归继续找出剩余字串与字典的匹配串,但是这样有一个问题就是如果有多个匹配然后选择的那个匹配接下来的字串没有单词与其匹配,那就会产生错误。然后我倒转一下思路,从s中找出子串与字典中的单词进行匹配,然后再将剩余的字串与字典中的单词再进行匹配,如果最后不成功再倒退回上一步找另外的子串,则到成功或者全部遍历为止。
bool wordBreak(string s,vector<strin>& wordDict)
{
if(s.length()==0) return true;
bool flag=false;
for(int i=0;i<=s.length();i++)
{
string temp=s.substr(0,i);
vector<string>::iterator it=find(wordDict.begin(),wordDict.end(),temp);
if(it!=wordDict.end())
{
if(temp.length()==s.length()) return true;
flag=wordBreak(s.substr(i),wordDict);
}
if(flag) return true;
}
return false;
}
但是这样提交会出现Time Limit Exceeded的错误。
去看Discuss里面的讨论,原来是用动态规划来解决的,但是我只是听过DP,没真正做过,需要学习一下。
bool wordBreak(string s, vector<string> &wordDict) {
if(wordDict.size()==0) return false;
vector<bool> dp(s.size()+1,false);
dp[0]=true;
for(int i=1;i<=s.size();i++)
{
for(int j=i-1;j>=0;j--)
{
if(dp[j])
{
string word = s.substr(j,i-j);
if(find(wordDict.begin(),wordDict.end(),word)!= wordDict.end())
{
dp[i]=true;
break; //next i
}
}
}
}
return dp[s.size()];
}
beats 100.00 % of cpp submissions.