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 ) O()
- Space complexity :
O
(
)
O\left ( \right )
O()
思路:
每次找一个能匹配的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 ) O()
- Space complexity :
O
(
)
O\left ( \right )
O()
思路:
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()];
}
};