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.
Example 1:
Input: s = "leetcode", wordDict = ["leet", "code"] Output: true Explanation: Return true because"leetcode"
can be segmented as"leet code"
.
Example 2:
Input: s = "applepenapple", wordDict = ["apple", "pen"] Output: true Explanation: Return true because"
applepenapple"
can be segmented as"
apple pen apple"
. Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] Output: false
思路:
两种方案,一种递归,一种动态规划。递归方法超时。
1 递归:
bool helper(string s, unordered_set<string> wordSet){
if (s.empty()) return true;
for (int i = 0; i < s.size(); i++){
string profix = s.substr(0, i + 1);
if (wordSet.find(profix) != wordSet.end()){
string nextS = s;
nextS.erase(0, i + 1);
if (helper(nextS, wordSet))
return true;
}
}
return false;
}
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet;
for (string word : wordDict)
wordSet.insert(word);
return helper(s, wordSet);
}
2 动态规划
bool wordBreak2(string s, vector<string>& wordDict){
unordered_set<string> wordSet;
for (string word : wordDict)
wordSet.insert(word);
int sLen = s.size();
vector<bool> record(sLen, false);
for (int i = 0; i < sLen; i++){
string subS = s.substr(0, i+1);
if (wordSet.find(subS) != wordSet.end()){
record[i] = true;
continue;
}
for (int j = 1; j < i+1; j++){
string subS = s.substr(i - j + 1, j);
if (wordSet.find(subS) != wordSet.end())
record[i] = record[i - j] || record[i];
}
}
return record[sLen - 1];
}