HashTable-720-Longest Word in Dictionary

Description:

Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order.
If there is no answer, return the empty string. 

Example 1:

Input: 
words = ["w","wo","wor","worl", "world"]
Output: "world"
Explanation: 
The word "world" can be built one character at a time by "w", "wo", "wor", and "worl".

Example 2:

Input: 
words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
Output: "apple"
Explanation: 
Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply".
Note:
All the strings in the input will only contain lowercase letters.
The length of words will be in the range [1, 1000].
The length of words[i] will be in the range [1, 30].

Solution:

//构造前缀树。前缀树中每个Node都包含一个字符c(root为0),以及end(用来存储字符串在words中的下标,在之后的DFS中方便取出字符串进行比较),以及一个Map(键为子节点对应的字符,值为子节点)。需要特别注意的是前缀树的构造方式,如果节点没有对应的子节点,则会新建节点,然后沿着该新建的节点继续向下构建(这就形成了一条路径,即为前缀)。
class Solution {
    public String longestWord(String[] words) {
        Trie trie = new Trie();
        int index = 0;
        for (String word: words) {
            trie.insert(word, ++index); //indexed by 1
        }
        trie.words = words;
        return trie.dfs();
    }
}
class Node {
    char c;
    HashMap<Character, Node> children = new HashMap();
    int end;
    public Node(char c){
        this.c = c;
    }
}

class Trie {
    Node root;
    String[] words;
    public Trie() {
        root = new Node('0');
    }

    public void insert(String word, int index) {
        Node cur = root;
        for (char c: word.toCharArray()) {
            cur.children.putIfAbsent(c, new Node(c));
            cur = cur.children.get(c);
        }
        cur.end = index;
    }

    public String dfs() {
        String ans = "";
        Stack<Node> stack = new Stack();
        stack.push(root);
        while (!stack.empty()) {
            Node node = stack.pop();
            if (node.end > 0 || node == root) {
                if (node != root) {
                    String word = words[node.end - 1];
                    if (word.length() > ans.length() ||
                            word.length() == ans.length() && word.compareTo(ans) < 0) {
                        ans = word;
                    }
                }
                for (Node nei: node.children.values()) {
                    stack.push(nei);
                }
            }
        }
        return ans;
    }
}

Better Solution:

//注意,这里之所以没有像上一个解法用String.compareTo()是因为使用了数组,而数组的顺序就代表了字母的大小,所以同等大小,选在排在前面的。
class Solution {

    private final int NUM_LETTERS = 26;

    class Trie {
        Trie[] next = new Trie[NUM_LETTERS];
        String word = null;
    }

    Trie root = new Trie();

    private void addWord(String s) {
        Trie curr = root;
        for(char c: s.toCharArray()) {
            int index = c - 'a';
            if(curr.next[index] == null) {
                curr.next[index] = new Trie();
            }
            curr = curr.next[index];
        }
        curr.word = s;
    }

    public String longestWord(String[] words) {
        root.word = "";
        for(String word: words) {
            addWord(word);
        }
        Trie curr = root;
        return DFS(curr);
    }

    private String DFS(Trie curr) {
        String result = curr.word;
        for(int i = 0; i < NUM_LETTERS; i++) {
            if(curr.next[i] != null && curr.next[i].word != null) {
                String subResult = DFS(curr.next[i]);
                if(subResult.length() > result.length()) {
                    result = subResult;
                }
            }
        }
        return result;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值