Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words.
A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.
Example:
Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".
Note:
- The number of elements of the given array will not exceed
10,000
- The length sum of elements in the given array will not exceed
600,000
. - All the input string will only include lower case letters.
- The returned elements order does not matter.
DFS求解,中间加入剪枝,程序如下所示:
class Solution {
Set<String> set = new HashSet<>();
List<String> list = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
private int cnt = 0;
public List<String> findAllConcatenatedWordsInADict(String[] words) {
for (String val : words){
set.add(val);
}
for (String val : words){
cnt = 0;
dfs(val, val.length(), 0, 0);
if (cnt >= 2){
list.add(val);
map.put(val, cnt);
}
}
return list;
}
public void dfs(String s, int sLen, int begin, int cur){
if (begin > sLen){
return ;
}
if (begin == sLen ){
cnt = Math.max(cur, cnt);
return;
}
if (cnt >= 2){
return;
}
for (int i = begin; i < sLen; ++ i){
if (i+1 <= sLen){
String st = s.substring(begin, i+1);
if (set.contains(st)){
String str = s.substring(i+1, sLen);
if (map.containsKey(str)){
cnt = cur + map.get(str);
return;
}
dfs(s, sLen, i + 1, cur+1);
}
}
}
}
}