题目链接:https://leetcode.com/problems/word-break-ii/
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”].
思路:
1.回溯法
根据字典创建一个字典树,根据s遍历字典树,当遇到一个结点是word的时候,递归处理剩余字符串(将剩余字符串从字典树root结点开始遍历),且继续往下层遍历。
当字符串所有字符都能被遍历到且最后一个字符的结点是word结点,则保存结果。当遇到无法识别的字符(即不在字典树的字符),则返回停止递归。当遍历到最后一个字符不是word结点,则返回停止递归。
2.遍历字符串,判断每一位到前一个字符串之间的字符串是否能组成一个word,并保存结果。得到一个pos数组,每一个元素保存的是从上一个word下标到当前下标之间的字符串能组成的word。然后根据上述结果dfs。
算法2:
List<String> res = new ArrayList<String>();
public List<String> wordBreak(String s, Set<String> wordDict) {
ArrayList<String>[] pos = new ArrayList[s.length()+1];
for (int i = 0; i < s.length(); i++) {
if (i == 0 || pos[i] != null) {// 0~i-1之间字符串可break
for (int j = i + 1; j <= s.length(); j++) {// 剩余字符串i~j
String sub = s.substring(i, j);
if (wordDict.contains(sub)) {// 找到下一个单词
if (pos[j] == null) {
pos[j] = new ArrayList<String>();
}
pos[j].add(sub);
}
}
}
}
if(pos[s.length()]==null){
return res;
}else{
dfs(pos,s,"",s.length());
}
return res;
}
public void dfs(List<String>[] pos,String s,String curr,int idx){
if(idx==0){
res.add(curr.trim());
return;
}
for(String word:pos[idx]){
String tmp=word+" "+curr;
dfs(pos,s,tmp,idx-word.length());
}
}