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 children;
    TrieNode() {
        this->is_end = false;
        children = vector(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;

    }
};