题目
给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词 。
连接词 定义为:一个完全由给定数组中的至少两个较短单词组成的字符串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/concatenated-words
代码
//字典树+深度优先搜索
class Solution {
Trie trie=new Trie(); //字典树
public List<String> findAllConcatenatedWordsInADict(String[] words) {
List<String> ans=new ArrayList<String>(); //用来存放答案
Arrays.sort(words,(a,b)->a.length()-b.length()); //将words按字符串长度进行排序
for(int i=0;i<words.length;i++){
String word=words[i];
if(word.length()==0){ //如果字符串长度为0,跳过
continue;
}
if(dfs(word,0)){ // 利用深度优先搜索查找是不是连接词
//如果是,则加入结果中
ans.add(word);
}else{
//如果不是,则将该词放入字典树中
insert(word);
}
}
return ans;
}
public boolean dfs(String word,int start){
if(word.length()==start){ //如果字符串所有字符全在字典树中,则是连接词,返回TRUE
return true;
}
Trie node=trie;
for(int i=start;i<word.length();i++){
//查找字典树
char ch=word.charAt(i);
int index=ch-'a';
node=node.children[index];
if(node==null){//如果字典树中不存在,则返回FALSE
return false;
}
if(node.isEnd){ //如果达到字典树的结尾,那么有可能是另一个单词拼接而成,因此重新搜索
if(dfs(word,i+1)){
//方法和上面同理
return true;
}
}
}
return false;
}
//将单词插入到字典树中
public void insert(String word){
Trie node=trie;
for(int i=0;i<word.length();i++){
char ch=word.charAt(i);
int index=ch-'a';
if(node.children[index]==null){
node.children[index]=new Trie();
}
node=node.children[index];
}
node.isEnd=true;
}
}
class Trie{
Trie[] children;
boolean isEnd;
public Trie(){
children=new Trie[26];
isEnd=false;
}
}