BiruLyu
6/25/2017 - 1:11 AM

472. Concatenated Words(1st).java

class TrieNode {
    TrieNode[] children;
    boolean hasWord;
    boolean isComb;
    boolean isAdd;
    String word;
    
    public TrieNode() {
        children = new TrieNode[26];
        hasWord = false;
        isComb = false;
        isAdd = false;
        
    }
}
public class Solution {
    
    public TrieNode buildTrieTree(String[] words) {
        TrieNode root = new TrieNode();
        for (String word : words) {
            TrieNode temp = root;
            if (word.length() == 0) continue; //[""]
            for (char c : word.toCharArray()) {
                int idx = c - 'a';
                if (temp.children[idx] == null) temp.children[idx] = new TrieNode();
                temp = temp.children[idx];
            }
            temp.hasWord = true;
            temp.word = word;
        }
        return root;
    }
    public List<String> findAllConcatenatedWordsInADict(String[] words) {
        TrieNode root = buildTrieTree(words);
        List<String> res = new ArrayList<String>();
        dfs(root, root, 0, res);
        return res;
    }
    
    public void dfs(TrieNode root, TrieNode node, int times, List<String> res) {
        if (node.hasWord && !node.isAdd && times > 1) {
            res.add(node.word);
            node.isAdd = true;
            node.isComb = true;
        }
        helper(root, node, root, times, res);
    }
    
    public void helper(TrieNode root, TrieNode node1, TrieNode node2, int times, List<String> res) {
        if (node2.isComb) return;
        if (node2.hasWord) {
            dfs(root, node1, times + 1, res);
        } 
        
        for (int i = 0; i < 26; i++) {
            if (node1.children[i] != null && node2.children[i] != null) {
                helper(root, node1.children[i], node2.children[i], times, res);
            }
        }
    }
}
public class Solution {
    public List<String> findAllConcatenatedWordsInADict(String[] words) {
        List<String> res = new ArrayList<>();
        if(words == null || words.length == 0) return res;
        TrieNode root = new TrieNode();
        for(String s : words) add(root, s);
        for(String s : words){
            if(dfs(root, root, s, 0)) res.add(s);
        }
        return res;
    }
    
    private boolean dfs(TrieNode root, TrieNode cur, String s, int index){
        if(index == s.length()) return cur.word != null && cur.word != s;
        if(cur.children[s.charAt(index)-'a'] == null) return false;
        if(cur.children[s.charAt(index)-'a'].word != null && dfs(root, root, s, index+1)) return true;
        return dfs(root, cur.children[s.charAt(index)-'a'], s, index+1);
    }
    
    class TrieNode{
        String word;
        TrieNode[] children;
        TrieNode(){
            word = null;
            children = new TrieNode[26];
        }
    }
    
    private void add(TrieNode root, String s){
        if(s.length()==0) return;
        TrieNode cur = root;
        for(int i = 0; i < s.length(); i++){
            char c = s.charAt(i);
            if(cur.children[c-'a'] == null) cur.children[c-'a'] = new TrieNode();
            cur = cur.children[c-'a'];
        }
        cur.word = s;
    }
}