Longest word in Dictionary

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

思路1: 用trie存word,然后扫描两遍;扫描第二次的时候,看每一步是否是isword,如果是,更新最长的word,如果跟最长的wordlength 相等,compareword,取lexicographical order最小的;

class Solution {
    class TrieNode {
        public TrieNode[] children;
        public boolean isword;
        public String word;
        public TrieNode() {
            this.children = new TrieNode[26];
            this.isword = false;
            this.word = null;
        }
    }
    
    class Trie {
        public TrieNode root;
        public Trie() {
            this.root = new TrieNode();
        }
        
        public void insertWord(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 boolean searchWord(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'].isword) {
                    return false;
                }
                cur = cur.children[c - 'a'];
            }
            return cur.isword;
        }
    }
    
    public String longestWord(String[] words) {
        String longestWord = "";
        Trie trie = new Trie();
        for(String word: words) {
            trie.insertWord(word);
        }
        
        for(String word: words) {
            if(trie.searchWord(word)) {
                if(word.length() > longestWord.length() 
                   || (word.length() == longestWord.length() && word.compareTo(longestWord) < 0)) {
                    longestWord = word;
                } 
            }
        }
        return longestWord;
    }
}

思路2:用trie做,可以做到O(n*L); 这题巧妙的是,build trie之后,可以bfs,层级的搜,要得到smallest lexicographical order.那么我最后搜集到的res,就是字典序最小的,因为是从后往前搜,然后最后一个答案就是最前面的;

class Solution {
    public class TrieNode {
        public TrieNode[] children;
        public String word;
        public boolean isword;
        public TrieNode () {
            this.children = new TrieNode[26];
            this.word = null;
            this.isword = false;
        }
    }
    
    public 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 String longestWord(String[] words) {
        Trie trie = new Trie();
        for(String word: words) {
            trie.insert(word);
        }
        
        String result = "";
        Queue<TrieNode> queue = new LinkedList<>();
        queue.offer(trie.root);
        while(!queue.isEmpty()) {
            int size = queue.size();
            for(int i = 0; i < size; i++) {
                TrieNode node = queue.poll();
                for(int j = 25; j >= 0; j--) {
                    if(node.children[j] != null && node.children[j].isword) {
                        result = node.children[j].word;
                        queue.offer(node.children[j]);
                    }
                }
            }
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值