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 I一样,简单的使用递归会超时。结合前一题的解法做剪枝,只对能够被拆解的子字符串进行后续DFS,这样可以有效减少DFS的搜索空间。
可以直接照搬前一版本的代码。
public List<String> wordBreak(String s, Set<String> dict) { List<String> ret = new ArrayList<String>(); // An important pruning here, by resuing the version I. // Return an empty collection if no solution exists. if (!isBreakable(s, dict)) { return ret; } dfs(s, dict, 0, "", ret); return ret; } private boolean isBreakable(String s, Set<String> dict) { // dp[i][j] represents the substring that starts at i and ends at j, // where j is exclusive. // dp[*][0] is wasted. boolean[][] dp = new boolean[s.length()][s.length() + 1]; for (int len = 1; len <= s.length(); ++len) { for (int start = 0; start <= s.length() - len; ++start) { int end = start + len; String substr = s.substring(start, end); if (len == 1) { dp[start][end] = dict.contains(substr); } else { if (dict.contains(substr)) { dp[start][end] = true; continue; } // Try to partition the word. for (int leftLen = 1; leftLen < len; ++leftLen) { int leftEnd = start + leftLen; if (dp[start][leftEnd] && dp[leftEnd][end]) { dp[start][end] = true; break; } } } } } return dp[0][s.length()]; } private void dfs(String s, Set<String> dict, int start, String sentence, List<String> sentences) { if (start == s.length()) { // Remove the leading space before adding it to the result collection. sentences.add(sentence.substring(1)); return; } for (int len = 1; start + len <= s.length(); ++len) { int end = start + len; String str = s.substring(start, end); if (dict.contains(str)) { dfs(s, dict, end, sentence + " " + str, sentences); } } }