给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]
代码
class Solution {
Map<Integer,List<List<String>>> listMap=new HashMap<>();
public List<String> wordBreak(String s, List<String> wordDict) {
Trie trie=new Trie();
Set<Integer> set=new HashSet<>();
for(String c:wordDict) {
set.add(c.length());
trie.insert(c);
}
List<String> ret=new ArrayList<>();
List<List<String>> resss=awordBreak(s,0,trie,set);
for(java.util.List<String> list:resss) ret.add(String.join(" ",list));//添加空格
return ret;
}
public List<List<String>> awordBreak(String s, int loc,Trie trie,Set<Integer> set) {
if(!listMap.containsKey(loc)){
List<List<String>> temp=new LinkedList<List<String>>();
if(loc==s.length())
temp.add(new ArrayList<>());
for(int c:set)//测试字典的所有单词
{
if(loc+c<=s.length()){
String need=s.substring(loc,loc+c);
if(trie.search(need)){//该单词合法
List<List<String>> nexts= awordBreak(s,loc+c,trie,set);//递归获取字符串后部分返回的单词序列
for(List<String> list:nexts)//将不同的单词序列与当前单词连接
{
LinkedList<String> next=new LinkedList<>(list);
next.offerFirst(need);
temp.add(next);
}
}
}
}
listMap.put(loc,temp);
}
return listMap.get(loc);
}
class TrieNode {//字典树
private TrieNode[] links;
private final int r=26;
private boolean isEnd;
public TrieNode() {
this.links = new TrieNode[r];
}
public boolean contains(char c) {
return links[c-'a']!=null;
}
public void put(char c,TrieNode node) {
links[c-'a']=node;
}
public TrieNode get(char c) {
return links[c-'a'];
}
public boolean isEnd() {
return isEnd;
}
public void setEnd() {
isEnd = true;
}
}
class Trie{
private TrieNode root;
public Trie() {
this.root = new TrieNode();
}
public void insert(String s)
{
TrieNode cur=root;
for(int i=0;i<s.length();i++)
{
if(!cur.contains(s.charAt(i)))
{
cur.put(s.charAt(i),new TrieNode());
}
cur=cur.get(s.charAt(i));
}
cur.setEnd();
}
public boolean search(String s)
{
TrieNode cur=root;
for(int i=0;i<s.length();i++)
{
if(cur.contains(s.charAt(i)))
{
cur=cur.get(s.charAt(i));
}else return false;
}
return cur.isEnd;
}
}
}