Word Break II 解答
Question
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"]
.
Solution
这题的基本思路是用recursion,每次都只研究第一刀切在哪儿,然后对剩下的substring做递归。但是我们发现其实可以借助DP的思想,存下来部分中间结果值。这种思想也叫 Memorized Recursion。
Memorized recursion并不是一个很好的方法,但是当遇到time limit exceed时可以想到它来拿空间换时间
1 class Solution: 2 # @param s, a string 3 # @param dict, a set of string 4 # @return a list of strings 5 def wordBreak(self, s, dict): 6 self.dict = dict 7 # cache stores tmp results: key: substring value: list of results 8 self.cache = {} 9 return self.break_helper(s) 10 11 def break_helper(self, s): 12 combs = [] 13 if s in self.cache: 14 return self.cache[s] 15 if len(s) == 0: 16 return [] 17 18 for i in range(len(s)): 19 if s[:i+1] in self.dict: 20 if i == len(s) - 1: 21 combs.append(s[:i+1]) 22 else: 23 sub_combs = self.break_helper(s[i+1:]) 24 for sub_comb in sub_combs: 25 combs.append(s[:i+1] + ' ' + sub_comb) 26 27 self.cache[s] = combs 28 return combs
第二种思路:先用DP,再用DFS
dp[i] 为list<String>表示以i结尾的在word dict中的词,并且满足dp[i - wordLen]不是null。
DFS从dp[len]开始,遍历可能的词。
1 public class Solution { 2 public List<String> wordBreak(String s, Set<String> wordDict) { 3 List<String> result = new ArrayList<>(); 4 if (wordDict == null || s == null) { 5 return result; 6 } 7 int len = s.length(); 8 ArrayList<String>[] dp = new ArrayList[len + 1]; 9 dp[0] = new ArrayList<String>(); 10 for (int i = 0; i < len; i++) { 11 if (dp[i] != null) { 12 for (int j = i + 1; j <= len; j++) { 13 String sub = s.substring(i, j); 14 if (wordDict.contains(sub)) { 15 if (dp[j] == null) { 16 dp[j] = new ArrayList<String>(); 17 } 18 dp[j].add(sub); 19 } 20 } 21 } 22 } 23 if (dp[len] == null) { 24 return result; 25 } 26 // dfs 27 dfs(dp, result, "", len); 28 return result; 29 } 30 31 private void dfs(ArrayList<String>[] dp, List<String> result, String tail, int curPos) { 32 if (curPos == 0) { 33 result.add(tail.trim()); 34 return; 35 } 36 for (String str : dp[curPos]) { 37 String curStr = str + " " + tail; 38 dfs(dp, result, curStr, curPos - str.length()); 39 } 40 } 41 }