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”.
解:
dp方法
dp[i]用来保存string sequence 从开头到第i-1的位置是不是合法的word sequence
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++)
{
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; //next i
}
}
}
}
return dp[s.size()];
}
用字典树可以加快一下搜索
const int MAX_CHAR =52;
struct TrieNode
{
vector<TrieNode*> children;
int freq;
bool leaf;
TrieNode():leaf(false),children(MAX_CHAR,nullptr),freq(0)
{
}
};
class Trie
{
private:
TrieNode* root;
public:
Trie():root(nullptr){}
int index(char c)
{
if(c>='a')return c-'a';
else return c-'A';
}
template<typename Container>
void addDict(Container dict)
{
if(root==nullptr)root=new TrieNode();
auto ptr=root;
for(auto& w:dict)
{
ptr=root;
bool exist=true;
for(auto& c:w)
{
auto next=ptr->children[index(c)];
if(next==nullptr)
{
ptr->children[index(c)]=new TrieNode();
exist=false;
}
ptr=ptr->children[index(c)];
}
ptr->leaf=true;
if(exist)ptr->freq++;
else ptr->freq=1;
}
}
bool breakWord(string s,int start,vector<int>&dp)
{
if(dp[start]>=0)return dp[start];
auto ptr=root;
for(int i=start;i<s.size();++i)
{
char c=s[i];
if(ptr==nullptr)return false;
if(ptr->leaf)
{
bool tmp=breakWord(s,i,dp);
dp[i]=tmp;
if(tmp)return true;
}
ptr=ptr->children[index(c)];
}
if(ptr==NULL)return false;
return ptr->leaf;
}
};
class Solution {
public:
bool wordBreak(string s, unordered_set<string>& wordDict) {
Trie t;
vector<int>dp(s.size(),-1);
t.addDict(wordDict);
return t.breakWord(s,0,dp);
}
};