140. Word Break II
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: []
class Solution { public List<String> wordBreak(String s, List<String> wordDict) { List<String> res = new ArrayList(); int l = s.length(); boolean[] dp = new boolean[l + 1]; dp[0] = true; for(int i = 1; i <= l; i++){ for(int j = 0; j < i; j++){ if(dp[j] && wordDict.contains(s.substring(j, i))){ dp[i] = true; } } } if(dp[s.length()] == false) return res; help(s, wordDict, res, 0, ""); return res; } public void help(String s, List<String> wordDict, List<String> res, int start, String tmp){ if(start == s.length()){ res.add(tmp); return; } if(tmp.length() != 0) tmp += " "; for(int i = start; i < s.length(); i++){ String word = s.substring(start, i+1); if(!wordDict.contains(word)) continue; help(s, wordDict, res, i + 1, tmp + word); } } }
需要先判断是否能进行word break再通过dfs求path。
public class Solution { HashMap<String,List<String>> map = new HashMap<String,List<String>>(); public List<String> wordBreak(String s, List<String> wordDict) { if(map.containsKey(s)) { return map.get(s); } List<String> res = new ArrayList<String>(); if(s == null || s.length() == 0) { return res; } if(wordDict.contains(s)) { res.add(s); } for(int i = 1 ; i < s.length() ; i++) { String t = s.substring(i); if(wordDict.contains(t)) { List<String> temp = wordBreak(s.substring(0 , i) , wordDict); if(temp.size() != 0) { for(int j = 0 ; j < temp.size() ; j++) { res.add(temp.get(j) + " " + t); } } } } map.put(s , res); return res; } }
dfs + memorization ≈ dp
用hashmap存已有的string对应的list。然后开始找分割点,分割点前继续dfs,分割点后直接检查是否存在于dict中。
从后往前,如果这个屁股string存在于dict中,就找它前面这个整串的可能的解,比如得到了temp,那我们就需要对每个temp(每种可能)后面加上屁股string,最后更新map和返回当前的解。
https://www.youtube.com/watch?v=JqOIRBC0_9c&ab_channel=HuaHua
从后往前
public class Solution { public List<String> wordBreak(String s, List<String> wordDict) { return DFS(s, wordDict, new HashMap<String, LinkedList<String>>()); } // DFS function returns an array including all substrings derived from s. List<String> DFS(String s, List<String> wordDict, HashMap<String, LinkedList<String>>map) { if (map.containsKey(s)) return map.get(s); LinkedList<String>res = new LinkedList<String>(); if (s.length() == 0) { res.add(""); return res; } for (String word : wordDict) { if (s.startsWith(word)) { List<String>sublist = DFS(s.substring(word.length()), wordDict, map); for (String sub : sublist) res.add(word + (sub.isEmpty() ? "" : " ") + sub); } } map.put(s, res); return res; } }
从前往后