LeetCode打卡day17

117 阅读1分钟

“Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情。”

一、题目描述:

720. 词典中最长的单词

给出一个字符串数组 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. 暴力模拟

所求的答案要求为

  • 所给的words 中有组成该结果字符串ans的从1~n长度的的字符串,例如单词"world"数组words中有"w", "wo", "wor", 和 "worl"。
  • ans长度最长
  • ans的字典序即a~z排序最小

因此我们可以暴力模拟,遍历words数组words[i],使用while循环判断数组中是否有words.includes(words[i].slice(0,length-1)),若条件满足,判断长度是否大于之前确定的最长的答案,若长度等于判断字典序的大小

/**
 * @param {string[]} words
 * @return {string}
 */
var longestWord = function(words) {
    let maxl=0,index=-1,n=words.length;
    if(n===0)return ''
    for(let i=0;i<n;i++){
        
        let len=words[i].length
        if(len>=maxl){
            let tmp=len-1

            while(tmp>=1&&words.includes(words[i].slice(0,tmp))){
                tmp--;
            }
            if(tmp===0){
                if(index===-1||len>maxl||words[i]<words[index]){
                    
                    index=i
                    maxl=len
                }
            }
        }else continue;
    }
    return index===-1?'':words[index]
};
  1. 优化 排序+集合 我们发现上面的方法对于每一个 "wo", "wor", 和 "worl"都要判断"w","wo", "wor"等等,占用许多无用空间,我们用set集合来存储满足条件的字符串,这样判断新的字符串我们只需要判断words[i].slice(0,length-1)是否在集合里面,不需要循环。

而为了只需要判断words[i].slice(0,length-1),我们得保证set中加入的数顺序为长度顺序,即不能先worl再wor。因此我们需要对他们进行按长度进行升序排序

我们希望第一个大于最大长度的字符串的字典序最小,因此当长度相同时按字典序升序排列,这样第一个满足条件的就是同等长度下字典序最小的,更新最大长度和答案。同时我们也要将满足所给的words 中有组成该结果字符串ans的从1~n长度的的字符串,加入集合set中进行后续长度增加后的判断

/**
 * @param {string[]} words
 * @return {string}
 */
var longestWord = function(words) {
    let maxl=0,ans='',n=words.length;
    if(n===0)return ''
    words.sort((a,b)=>{
        if(a.length!==b.length)return a.length-b.length
        return a.localeCompare(b)
    })
    let set=new Set()
    set.add('')
    for(let i of words){
        if(set.has(i.slice(0,i.length-1))){
            set.add(i)
            if(i.length>maxl){
                    maxl=i.length
                    ans=i
                }
        }
    }
    return ans
};