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, givens = "catsanddog",dict = ["cat", "cats", "and", "sand", "dog"].A solution is ["cats and dog", "cat sand dog"].
Difficulty: 98, referring to other people's ideas: the requirements for this question are similar to those of word break, but the returned results should not only know whether it can be break, but also return all valid results if it can. In general, this requirement will reduce the effect of dynamic planning, because we need to record all valid results in the process, the intermediate operation will make the complexity of the algorithm no longer a two-layer loop of dynamic planning, because the constant operation is required in each iteration, and the final complexity will mainly depend on the number of results, it also occupies a lot of space, because not only do you need to save the final results, including the valid results in the middle, but you also need to save them one by one. Otherwise, the subsequent historical information will not be available. Therefore, we will introduce two methods for this question. One is to use recursive solutions for brute force, and the other is dynamic planning similar to the idea of word break.
For the brute force solution, the code is relatively simple. Each time you maintain a current result set, traverse all the remaining substrings. If the substrings appear in the dictionary, save the result, and add the remaining recursive characters to the next layer. The idea is close to the routine we often use in NP problems such as N-Queens.
Brute force practices, similar to NP practices:
1 public ArrayList<String> wordBreak(String s, Set<String> dict) { 2 ArrayList<String> res = new ArrayList<String>(); 3 if(s==null || s.length()==0) 4 return res; 5 helper(s,dict,0,"",res); 6 return res; 7 } 8 private void helper(String s, Set<String> dict, int start, String item, ArrayList<String> res) 9 {10 if(start>=s.length())11 {12 res.add(item);13 return;14 }15 StringBuilder str = new StringBuilder();16 for(int i=start;i<s.length();i++)17 {18 str.append(s.charAt(i));19 if(dict.contains(str.toString()))20 {21 String newItem = item.length()>0?(item+" "+str.toString()):str.toString();22 helper(s,dict,i+1,newItem,res);23 }24 }25 }
Similar to the DP Method in word break, it is actually slightly modified on the basis of word break:
1 public class Solution { 2 public List<String> wordBreak(String s, Set<String> dict) { 3 ArrayList<ArrayList<String>> results = new ArrayList<ArrayList<String>>(); 4 if (s == null || s.length() == 0) return null; 5 boolean[] res = new boolean[s.length()+1]; 6 res[0] = true; 7 for (int k=0; k<=s.length(); k++) { 8 results.add(new ArrayList<String>()); 9 }10 results.get(0).add("");11 12 for (int i=1; i<=s.length(); i++) {13 for (int j=0; j<i; j++) {14 StringBuffer str = new StringBuffer(s.substring(j, i));15 if (res[j] && dict.contains(str.toString())) {16 res[i] = true;17 for (String kk : results.get(j)) {18 if (kk.equals(""))19 results.get(i).add(String.format("%s", str));20 else21 results.get(i).add(String.format("%s %s", kk, str));22 }23 }24 }25 }26 return results.get(s.length());27 }28 }
Another point to note is that the above two codes will time out in the leetcode, because leetcode has a very tricky test case, which cannot be break, but is very long, A large number of records and backtracking
There is a person with good practice: http://www.binglu.me/leetcode-word-break-and-word-break-ii/ can not time out
Leetcode: Word break II