The 2 brute-force ways O(2^n)
class Solution {
public:
bool bf(string s, unordered_set<string> &dict, int start) {
if (start==s.size()) return true;
int len=1;
while (len<=s.size()-start) {
if (dict.count(s.substr(start,len))>0) {
if( bf(s, dict, start+len)) {
return true;
}
}
len++;
}
return false;
}
bool wordBreak(string s, unordered_set<string> &dict) {
// Note: The Solution object is instantiated only once and is reused by each test case.
//return bf(s,dict,0);
if (dict.find(s)!=dict.end()) return true;
int len = s.size();
for (int i = 1; i < len; i++) {
string sub = s.substr(0, i);
if (dict.find(sub)!=dict.end()) {
string next = s.substr(i, len);
if (wordBreak(next, dict)) {
return true;
}
}
}
return false;
}
};
DP
class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
// Note: The Solution object is instantiated only once and is reused by each test case.
int len=s.size();
bool **seg = new bool*[len];
for (int i=0; i<len; i++) {
seg[i]=new bool[len-i];
}
for (int n=1; n<=len; n++) {
for (int i=0; i<=len-n; i++) {
seg[i][n-1]=false;
if (dict.find(s.substr(i,n))!=dict.end()) {
seg[i][n-1]=true;
continue;
}
for (int j=1; j<n; j++) {
if (seg[i][j-1]&&seg[i+j][n-1-j]) {
seg[i][n-1]=true;
break;
}
}
}
}
return seg[0][len-1];
}
};