LC-140 Word Break II
https://leetcode.com/problems/word-break-ii/
给一个字符串s,和一个字符串数组wordDict。现在要用空格把s分隔开,并且保证分割之后的每一部分都可以在wordDict中找到。以字符串数组的形式返回所有的可能分割方式。
例如s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
则返回结果为:["cat sand dog", "cats and dog"]
深度优先搜索:
从字符串头部开始匹配,使用start变量表示当前匹配的位置。对字典中的每个词在start处进行匹配,如果匹配到了,则记录下该词的下标,然后开始下一层搜索。如果字典中所有词都没有匹配到,则从start处开始没有正确答案。
当开始新的一层搜索时发现start已经走完了整个字符串,说明此时整个字符串s都已经被分配成了字典中的词,利用之前记录的更新到这个状态时所有的字典词的下标,更新结果。
这里我做了一个记忆化,利用Results二维数组存储结果,Results[start]表示了从start处开始所有可以匹配的上的字典里词的下标。如果从start处开始无解,则将Results[start]标记为-1,这样可以快速返回无解的信息,防止重复搜索(不对无解情况进行剪枝的话将会超时)
1 class Solution { 2 public: 3 vector<vector<int>> Results; 4 vector<int> WordsInDict; 5 vector<string> ret; 6 7 bool DFS(string &s, vector<string> &wordDict, int start) { 8 if (start >= s.length()) { 9 // all the sentence was allocated into wordDict 10 string NewRet = wordDict[WordsInDict[0]]; 11 for (int i = 1; i < WordsInDict.size(); i++) { 12 NewRet += " " + wordDict[WordsInDict[i]]; 13 } 14 ret.push_back(NewRet); 15 return true; 16 } 17 18 if (Results[start].size()) { 19 // the result of start has already been calculated 20 if (Results[start][0] < 0) { 21 // start has no valid result 22 return false; 23 } else { 24 int ResultsLen = Results[start].size(); 25 for (int i = 0; i < ResultsLen; i++) { 26 int DictWordIndex = Results[start][i]; 27 WordsInDict.push_back(DictWordIndex); 28 DFS(s, wordDict, start + wordDict[DictWordIndex].length()); 29 WordsInDict.pop_back(); 30 } 31 return true; 32 } 33 } else { 34 // the result has not yet been calculated, do the DFS 35 int DictLen = wordDict.size(); 36 bool HasValidResult = false; 37 for (int i = 0; i < DictLen; i++) { 38 if (string(s, start, wordDict[i].length()) == wordDict[i]) { 39 WordsInDict.push_back(i); 40 bool ok = DFS(s, wordDict, start + wordDict[i].length()); 41 WordsInDict.pop_back(); 42 if (ok) { 43 Results[start].push_back(i); 44 HasValidResult = true; 45 } 46 } 47 } 48 if (!HasValidResult) 49 Results[start].push_back(-1); 50 return HasValidResult; 51 } 52 } 53 54 vector<string> wordBreak(string s, vector<string> &wordDict) { 55 int len = s.length(); 56 for (int i = 0; i < len; i++) { 57 vector<int> v; 58 Results.push_back(v); 59 } 60 DFS(s, wordDict, 0); 61 62 return ret; 63 } 64 };

浙公网安备 33010602011771号