问题描述:
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.
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 = "catsanddog
" wordDict =["cat", "cats", "and", "sand", "dog"]
Output:[ "cats and dog", "cat sand dog" ]
Example 2:
Input: s = "pineapplepenapple" wordDict = ["apple", "pen", "applepen", "pine", "pineapple"] Output: [ "pine apple pen apple", "pineapple pen apple", "pine applepen apple" ] Explanation: Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = "catsandog" wordDict = ["cats", "dog", "sand", "and", "cat"] Output: []
解题思路:
我的思路是backtracking,但是超时了。
可以使用记忆化搜索来优化
参考了GrandYang的解法
利用一个map来存储一个字符串和这个字符串可以拆成的字典中的单词构成的句子的数组。
可以避免重复搜索。
代码:
backtracking:
class Solution { public: void dfs(string &s, set<string> &dict, string cur, vector<string> &ret, int maxL,int minL, int start){ if(start == s.size()){ cur.pop_back(); ret.push_back(cur); return; }else if(start > s.size()) return; for(int i = minL; i <= maxL && start + i <= s.size(); i++){ string temp = s.substr(start, i); if(dict.count(temp) != 0){ dfs(s, dict, cur+temp+" ", ret, maxL, minL, start+i); } } } vector<string> wordBreak(string s, vector<string>& wordDict) { vector<string> ret; if(wordDict.size() == 0) return ret; set<string> dicts; int maxL = 0, minL = INT_MAX; for(string s : wordDict){ dicts.insert(s); maxL = max(maxL, (int)s.size()); minL = min(minL, (int)s.size()); } dfs(s, dicts, "", ret, maxL, minL, 0); return ret; } };
记忆化搜索:
class Solution { public: vector<string> wordBreak(string s, vector<string>& wordDict) { unordered_map<string, vector<string>> m; return helper(s, wordDict, m); } vector<string> helper(string s, vector<string>& wordDict, unordered_map<string, vector<string>>& m) { if (m.count(s)) return m[s]; if (s.empty()) return {""}; vector<string> res; for (string word : wordDict) { if (s.substr(0, word.size()) != word) continue; vector<string> rem = helper(s.substr(word.size()), wordDict, m); for (string str : rem) { res.push_back(word + (str.empty() ? "" : " ") + str); } } return m[s] = res; } };