139. Word Break

Description：
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
Note:
The same word in the dictionary may be reused multiple times in the segmentation.
You may assume the dictionary does not contain duplicate words.
Difficulty：Medium
Example:

Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

方法1：深度搜索，超时

• Time complexity : O ( ) O\left (\right )
• Space complexity : O ( ) O\left ( \right )
思路：
每次找一个能匹配的segment，然后递归剩下的s以及全部dict，这里有一个技巧是要用每次return的|的结果，因为只要有一个true就ok。
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
return helper(s, 0, s.size()-1, wordDict);
}
bool helper(string &s, int l, int r, vector<string>& dict){
if(l == r+1) return true;
bool res = false;
for(int i = 0; i < dict.size(); i++){
if(r-l+1 >= dict[i].size()){
int j = 0;
for(;j < dict[i].size(); j++){
if(s[l+j] != dict[i][j])
break;
}
if(j == dict[i].size())
res |= helper(s, l+j, r, dict);
}
else{
continue;
}
}
return res;
}
};

方法2：动态规划

• Time complexity : O ( ) O\left (\right )
• Space complexity : O ( ) O\left ( \right )
思路：
dp[i] = {...|...dp[j] && s[j:i] in dict... |...} 0<=j<i大括号内相与
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
if(wordDict.size() == 0) return false;
unordered_set<string> dict;
for(auto w: wordDict)
dict.insert(w);
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 segment = s.substr(j, i-j);
if(dict.find(segment) != dict.end()){
dp[i] = true;
break;
}
}
}
}
return dp[s.size()];
}
};
01-27 115
07-02 299

05-06 197
12-18 280
10-30 95