力扣题解:词典中最长的单词

126 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

题目描述

原题链接 :

720. 词典中最长的单词 - 力扣(LeetCode)

给出一个字符串数组 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 <= words.length <= 1000
  • 1 <= words[i].length <= 30
  • 所有输入的字符串 words[i] 都只包含小写字母。

思路分析

  1. 关于排序,直接按照Array.sort()的默认排序,没有自定义,出来直接就是字典序(不明白评论区为啥都是先按长度、再按字典序,哪位大佬清楚欢迎赐教)。
  2. 在遍历words数组时,不用再依次遍历单词的每个字母,因为按照字典序排好后,依次按长度递增的顺序存入HashSet、再判断len-1部分的字符串是否已存在即可(例如从"a"开始存入HashSet,再遍历到"ap"时,会判断a是否已存在,如果不存在是不会存入到set的,所以只要set中存在,就说明前缀是完整的存在于words数组的)。

AC 代码

class Solution {
    
    public String longestWord(String[] words) {

        // 默认字典序,例如:a, ab, abc, b, bc, ...
        Arrays.sort(words);

        Set<String> set = new HashSet<>();
        String longestWord = "";
        for (String word: words) {          
            int len = word.length();
            // 只有当前len-1个字母组成的单词已经存入set时,继续添加到set里(否则就是不连续的单词)
            if (len == 1 || set.contains(word.substring(0, len - 1))) {
                // 如果当前单词长度大于longestWord的长度,则更新longestWord
                longestWord = len > longestWord.length() ? word : longestWord;
                set.add(word);
            }
        }

        return longestWord;
    }
}