Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog"
,
dict = ["cat", "cats", "and", "sand", "dog"]
.
A solution is ["cats and dog", "cat sand dog"]
.
这题是Word Break的follow up。现在不是判断能否被break,而是给出所有break的情况。如果用单纯的search+backtrack会TLE,这种做法如下:
class Solution(object): def wordBreak(self, s, wordDict): """ :type s: str :type wordDict: Set[str] :rtype: List[str] """ if not s or not wordDict: return [] maxlen = 0 for w in wordDict: maxlen = max(maxlen, len(w)) hash = set(wordDict) res = [] self.search(s, hash, res, [], 0, maxlen) res = self.gen_result(res, s) return res def search(self, s, hash, res, cur, index, maxlen): if index == len(s): res.append(cur + [index]) return cur.append(index) for i in xrange(1,maxlen+1): if s[index:index+i] in hash: self.search(s, hash, res, cur, index+i, maxlen) cur.pop() def gen_result(self, res, s): tmp = [] for i in xrange(len(res)): arr = [] for j in xrange(0,len(res[i])-1): arr.append(s[res[i][j] : res[i][j+1]]) tmp.append(' '.join(arr)) return tmp
如何改进呢~为何搜索复杂度高,主要在于重复分割,如果后面需要分割的子段前面曾经分割过,则再次处理时就比较浪费时间。一个以空间换时间的做法是将之前处理过的子串的所有可能都保存,是一种memory search的方法。以空间换取了时间。代码如下:
class Solution(object): def wordBreak(self, s, wordDict): """ :type s: str :type wordDict: Set[str] :rtype: List[str] """ #pure search and backtracking is TLE, using the memory search method, #ie, a dict object to store the result for the current tackling substr cache = {} result = self.helper(s, wordDict, cache) return result def helper(self, s, wordDict, cache): if s in cache: return cache[s] result = [] if s in wordDict: result.append(s) for i in xrange(1, len(s)): word = s[i:] if word in wordDict: rem = s[:i] prev = self.combine(word, self.helper(rem, wordDict, cache)) result += prev cache[s] = result + [] return result def combine(self, word, prev): #word is a string, and prev is a list of string, tmp = [] for i in xrange(len(prev)): tmp.append(prev[i] + ' ' + word) #注意这段一定要这样写,防止直接对prev的修改造成内存的直接修改,影响到cache. return tmp