Concatenated Words

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".

Idea: first insert the word into trie to determine whether it contains a string, and then use the root of trie to do DFS. Every time a word is found, continue recursion, index forward until word.length () and count> = 2 The representative is what I want; Note: cur is still going, but every time I want to search for words from root; cur = root;

class Solution {
    private class TrieNode {
        public TrieNode[] children;
        public boolean isword;
        public String word;
        public TrieNode () {
            this.children = new TrieNode[26];
            this.isword = false;
            this.word = null;
        }
    }
    
    private class Trie {
        public TrieNode root;
        
        public Trie () {
            this.root = new TrieNode();
        }
        
        public void insert(String word) {
            TrieNode cur = root;
            for(int i = 0; i < word.length(); i++) {
                char c = word.charAt(i);
                if(cur.children[c - 'a'] == null) {
                    cur.children[c - 'a'] = new TrieNode();
                }
                cur = cur.children[c - 'a'];
            }
            cur.isword = true;
            cur.word = word;
        }
    }
    
    public List<String> findAllConcatenatedWordsInADict(String[] words) {
        List<String> list = new ArrayList<String>();
        Trie trie = new Trie();
        for(String word: words) {
            trie.insert(word);
        }
        
        for(String word: words) {
           if(concatenate(trie.root, word, 0, 0)) {
               list.add(word);
           }
        }
        return list;
    }
    
    private boolean concatenate(TrieNode root, String word, int index, int count) {
        if(index == word.length()) {
            // 用count记录遇见了几个单词;
            return count >= 2;
        }
        TrieNode cur = root;
        for(int i = index; i < word.length(); i++) {
            char c = word.charAt(i);
            if(cur.children[c - 'a'] == null) {
                return false;
            }
            cur = cur.children[c - 'a'];
            if(cur.isword) {
                // 每次判断单词,都要从root开始判断,所以传入的参数始终是root;
                if(concatenate(root, word, i + 1 , count + 1)) {
                    return true;
                }
            }
        }
        return false;
    }
}

 

Published 710 original articles · Like 13 · Visits 190,000+

Guess you like

Origin blog.csdn.net/u013325815/article/details/105446298
Recommended