Word Break Problems
Word Break Problems
Given a string and dictionary, check if the string can be perfectly composed from dictionary words
Solution 1: DP[i] means the substring from start to position i can be formed using dictionary words. We push forward from there.
// 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];
}Solution 2: dp[i] means the farthest position we can reach + 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++)
{
// From back to front, if we can compose it, continue to next 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()];
}Find all perfect combinations separated by spaces
Solution: Memoized search
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;
// Base case: s is in dictionary
if (dict.count(s)) res.push_back(s);
// Iterate through split points
for(int i=1;i<s.size();++i) {
string right=s.substr(i);
if (!dict.count(right)) continue;
string left=s.substr(0, i);
// Recursively solve left part and right part, then add right word
vector<string> left_res = append(break_word(left, dict), right);
// Add to current solution
res.insert(res.end(), left_res.begin(), left_res.end());
}
// Memoize the result
mem[s]=res;
return mem[s];
}
private:
unordered_map<string, vector<string> > mem;
};#recursion #divide-and-conquer #dp