leetcode【简单】720、词典中最长的单词

这篇博客探讨了如何利用排序和哈希集合,以及字典树(Trie)数据结构,来解决从给定词典中找出最长可构建的单词的问题。示例展示了在不同场景下,如示例1和示例2,如何应用这两种方法找到符合条件的最长单词。这两种方法都确保了字典序最小的单词作为结果,并且在不存在解决方案时返回空字符串。
摘要由CSDN通过智能技术生成

给出一个字符串数组 words 组成的一本英语词典。返回 words 中最长的一个单词,该单词是由 words 词典中其他单词逐步添加一个字母组成。(注意,必须从一个字母开始)

若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。

示例 1:

输入:words = ["w","wo","wor","worl", "world"]
输出:"world"
解释: 单词"world"可由"w", "wo", "wor","worl"逐步添加一个字母组成。

示例 2:

输入:words = ["a", "banana", "app", "appl", "ap", "apply", "apple"]
输出:"apple"
解释:"apply""apple" 都能由词典中的单词组成。但是 "apple" 的字典序小于 "apply" 
 

思路1:排序+hash

class Solution {
    public String longestWord(String[] words) {
        Arrays.sort(words);
        Set<String>set=new HashSet<>();
        String res="";
        for(String s:words){
            if(s.length()==1||set.contains(s.substring(0,s.length()-1))){
                set.add(s);
                res=s.length()>res.length()?s:res;
            }
        }
        return res;
    }
}

思路2:字典树

注意和208、实现 Trie (前缀树)【中等】search()有点区别,每个前缀都必须在trie里,所以inDictionary()中,if(cur == null || !cur.exist)时都为false

class Solution {
    public String longestWord(String[] words) {
        Arrays.sort(words);
        String res="";
        Trie trie=new Trie();
        for(String s:words){
            trie.insert(s);
            if(trie.inDictionary(s) && s.length()>res.length()) res=s;
        }
        return res;
    }
}

class Trie{
    TrieNode root;

    public Trie(){
        root=new TrieNode();
    }
    public void insert(String s) {
        TrieNode cur = root;
        for (char c : s.toCharArray()) {
            if (cur.children[c - 'a'] == null) {
                cur.children[c - 'a'] = new TrieNode();
            }
            cur = cur.children[c - 'a'];
        }
        cur.exist = true;
    }
    public boolean inDictionary(String s) {
        TrieNode cur = root;
        for (char c : s.toCharArray()) {
            cur = cur.children[c - 'a'];
            if (cur == null || !cur.exist) {//每个前缀都必须在trie里
                return false;
            }
        }
        return cur.exist;
    }
}

class TrieNode {
    boolean exist;
    TrieNode[] children;

    TrieNode() {
        exist = false;
        children = new TrieNode[26];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值