472. 连接词(trie)
难度困难
给你一个 不含重复 单词的字符串数组 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"]
struct TrieNode { bool is_end; vector<TrieNode*> children; TrieNode() { this->is_end = false; children = vector<TrieNode*>(26); } }; class Solution { TrieNode* root = new TrieNode(); unordered_set<string> word_set = {}; vector<string> res; public: void insert(string word) { TrieNode* node = root; for(auto ch : word) { if (node->children[ch-'a'] == nullptr) { node->children[ch-'a'] = new TrieNode(); } node = node->children[ch-'a']; } node->is_end = true; } bool dfs(string target,int index, vector<int>& visited) { if (index == target.size()) { return true; } if (visited[index]!=-1) return visited[index]; TrieNode* node = root;
//每一个子单词都需要判断是否在字典树中 for(int i = index; i < target.size();i++) { int ii = target[i]-'a'; node = node->children[ii]; if (node == nullptr) return false; if (node->is_end) { if(dfs(target,i+1,visited)) { visited[index] = 1; return true; } } } visited[index] = 0; return false; } vector<string> findAllConcatenatedWordsInADict(vector<string>& words) { vector<string> ans; sort(words.begin(), words.end(), [&](const string & a, const string & b){ return a.size() < b.size(); }); for (int i = 0; i < words.size(); i++) { string word = words[i]; if (word.size() == 0) { continue; } vector<int> visited(word.size(), -1); if (dfs(word, 0, visited)) { ans.emplace_back(word); } else { insert(word); } } return ans; } };