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"]
.
請參考LeetCode-Word Break 查看該題的第一個版本:判斷是否可分詞成功。但是這一題,不僅要判斷是否可以分詞,還要找到所有的分詞結果。
第一題是用dp[i]表示 字符串s[0....i-1]是否可以分詞成功。
爲了記錄是怎麼分詞的,我們可以用dp[i]表示 字符串s[0.....i-1]的最後一個分詞word,則s[0.....i-1]的倒數第二個分詞即爲dp[o....i-word.length()-1]。但這種方法只能記錄一種分詞方法,因此有必要把 dp[i] 定義 List<String>,這樣就可以表示多種分詞方法,最後使用DFS搜索,找到所有的分詞方法。
例如對於上面的例子: s.length()=10, 則 dp[10] = {“cat”}, dp[7]={“and”,”sand”}, dp[4]={“cats”}, dp[3]={“cat”}, dp[0]={}, 其它的都爲null。
dfs搜索的時,可以從後向前,也可以從前向後,只要保證最終結果的順序即可。下面是用的從後向前搜索。
01 |
public class Solution {
|
02 |
public static List<String> wordBreak(String s, Set<String> dict) {
|
03 |
List<String> dp[] = new ArrayList[s.length()+ 1 ];
|
04 |
dp[ 0 ] = new ArrayList<String>();
|
05 |
for ( int i= 0 ; i<s.length(); i++){
|
07 |
if ( dp[i] == null ) continue ;
|
08 |
for (String word:dict){
|
09 |
int len = word.length();
|
11 |
if (end > s.length()) continue ;
|
12 |
if (s.substring(i,end).equals(word)){
|
14 |
dp[end] = new ArrayList<String>();
|
21 |
List<String> ans = new LinkedList<String>();
|
22 |
if (dp[s.length()] == null ) return ans;
|
23 |
ArrayList<String> tmp = new ArrayList<String>();
|
24 |
dfsStringList(dp,s.length(),ans, tmp);
|
28 |
public static void dfsStringList(List<String> dp[], int end,List<String> res, ArrayList<String> tmp){
|
30 |
String ans = tmp.get(tmp.size()- 1 );
|
31 |
for ( int i=tmp.size()- 2 ; i>= 0 ; i--)
|
32 |
ans += ( " " + tmp.get(i) );
|
36 |
for (String str:dp[end]){
|
38 |
dfsStringList(dp,end-str.length(), res, tmp);
|
39 |
tmp.remove(tmp.size()- 1 );
|
當然也有其他的解法,這個只是參考,效率其實還可以。