Word Break
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".
First, I tried backtracking algorithm, but I met Time Limit Exceeded error.
Backtracking:o(n!)
//can I reuse the words in dict?
//What should I return if s is an empty string?
//s = abc wordDict = "abc" ? what should I return?
class Solution {
public:
bool wordBreak(string s, unordered_set<string>& wordDict) {
//extreme case
if(s.size() == 0 || wordDict.empty() == true) return false;
return _wordBreak(s, wordDict);
}
bool _wordBreak(string s, unordered_set<string>& wordDict){
//base condition
if(s.size() == 0) return true;
//ordinary case
for(size_t i = 0; i < s.size(); i++){
if(wordDict.find(s.substr(0, i + 1)) != wordDict.end()){
//s.substr is found in dict
if(_wordBreak(s.substr(i + 1, -1), wordDict) == true){
return true;
}
}
}
return false;
}
};
Dynamic programming: o(n^2)
dp[i] = dp[j – 1] && s.substr(j, i – j + 1), 0 <= j <= i
//can I reuse the words in dict?
//What should I return if s is an empty string?
//s = abc wordDict = "abc" ? what should I return?
//the time complexity of backtracking algorithm is unbearable o(n!)
//Dynamic programmming solution
//o(n^2)
class Solution {
public:
bool wordBreak(string s, unordered_set<string>& wordDict) {
//extreme case
if(s.size() == 0 || wordDict.empty() == true) return false;
bool dp[s.size()];
memset(dp, false, sizeof(dp));
for(size_t i = 0; i < s.size(); i++){
for(int j = i; j >= 0; j--){
if(wordDict.find(s.substr(j, i - j + 1)) != wordDict.end()){
if(j == 0) dp[i] = true;
else if(dp[j - 1] == true) dp[i] = true;
}
}
}
return dp[s.size() - 1];
}
};
