题目来源:leetcode 472. 连接词
给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词 。
连接词 定义为:一个完全由给定数组中的至少两个较短单词组成的字符串。
示例 1:
输入:words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] 输出:["catsdogcats","dogcatsdog","ratcatdogcat"] 解释:"catsdogcats" 由 "cats", "dog" 和 "cats" 组成; "dogcatsdog" 由 "dog", "cats" 和 "dog" 组成; "ratcatdogcat" 由 "rat", "cat", "dog" 和 "cat" 组成。
示例 2:
输入:words = ["cat","dog","catdog"] 输出:["catdog"]
提示:
1 <= words.length <= 104 0 <= words[i].length <= 1000 words[i] 仅由小写字母组成 0 <= sum(words[i].length) <= 105
解题思路
字符串数组 words 长度不是大于1的一定不存在连接词
将words数组根据 word长度进行从小到大排序,排序后的words[0]一定不是连接词
定义setWord变量存放基础单词,避免从整个数组中has是否存在当前元素
定义ans变量存放连接词数组
定义dfs方法,判断变量curWord是否空,并返回num是否大于1,大于1说明是连接词
遍历curWord能否在普通单词数组中存在,不存在的话说明不是连接词。
存在在的话,suffixWord = curWord.substr(i+1)以及num++作为参数递归调用dfs方法
代码实现
/**
* @param {string[]} words
* @return {string[]}
*/
var findAllConcatenatedWordsInADict = function (words) {
if(!words.length > 1) return []
let len = words.length
let setWord = new Set()
let ans = []
const dfs = (curWord, num) => {
if (num > 1 && !curWord)return true;
let prefixWord = "";
for (let i = 0; i < curWord.length; i++) {
prefixWord += curWord[i];
if (setWord.has(prefixWord)) {
const suffixWord = curWord.substr(i+1);
if (dfs(suffixWord, num + 1)) return true
}
}
return false;
}
words.sort((a, b) => a.length - b.length);
setWord.add(words[0]);
for(let i = 1; i < len; i++){
if(dfs(words[i],0)){
ans.push(words[i])
}else{
setWord.add(words[i])
}
}
return ans
};