720. 词典中最长的单词(字典序排序)

419 阅读4分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

每日刷题第66天 2021.03.17

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" 

思路分析

最开始的思路

  • 将数组中所有的字符串进行字典序排序并且还要将其长度进行排序,but自己不会自定义sort函数,就只将数组中的所有的字符串进行字典序排序。
    • 举例:原数组[b,d,be,ff,dc,dcs,bef]
    • 只按字典序排序后:[b,be,bef,d,dc,dcs,ff]
  • 对于排序好的数组,倒着遍历每一个字符串元素words[i]。根据题意可知:每个符合要求的字符串都是从其他单词逐步添加得来的,也就是每次只会多一个字母,那么还需要截取判断words[i]的每一个字字符串是否包含在数组中即可。
  • 与此同时,还需要找字典序最小的。那么记录当前的符合要求的字符串的长度为pre,只有后续的符合要求字符串的长度大于或者等于pre才会重新记录,并更新当前符合要求的字符串。

分析

  • 上述的解法存在一些问题和没必要的判断,就是对于数组中的每一个字符串都需要判断,因为排序后的数组中并不是将相同长度的字符串排在一起,而仅仅是排列了字典序(根据第一个字母的字典序进行排序)。
    • 解决方法:使用自定义的排序函数,那么就可以减少遍历整个数组,只需要遍历找到符合要求的第一个既是答案。

学习更好的解题思路

基础知识sort函数

  • sort()方法,用于数组元素的排序。排序可以是字母或是数字,并按升序或者降序。
    • 默认:按字母的升序排序。因此排序后会出现:'40','5'这样的情况。
  • 如果想要对数字进行排序,需要通过一个函数作为参数来调用
// 升序排序
sort((a, b) => a - b);
  • 注意⚠️:方法会改变原数组

自定义sort函数

  • 利用排序函数function中的返回值。sort() 方法比较两个值时,将值发送给比较函数,根据返回的(负、零、正)值对值进行排序。
    • 返回-1
    • 返回1
  • 对数组中字符串按照字典序排序(降序排序)的基础上,还需要按照长度排序(升序排序)
    • 举例子:变量a,b return a - b;
    • 假设a小于b,那么最终的值为负数,sort函数会将a排在b的前面
    • 假设a大于b,那么最终的值为正数,sort函数会将b排在a的前面
words.sort((a, b) => {
  // 当a的长度大于b的长度时,将a排在b的前面
  if(a.length > b.length) return -1;
  // 当a的长度小于b的长度时,将b排在a的前面
  else if(a.length < b.length) return 1;
  // 当a的值大于b的时候,将a排在b的后面;否则将a排在b的后面
  else return a > b ? 1 : -1;
})

AC代码

/**
 * @param {string[]} words
 * @return {string}
 */
var longestWord = function(words) {
  // 字典序排序并且结合字符串长度排序
  words.sort((a, b) => {
    if(a.length > b.length) return -1;
    else if(a.length < b.length)  return 1;
    else {
      return a > b ? 1 : -1;
    }
  });
  // console.log(words)
  let len = words.length;
  let ans = '';
  // 依次判断字符串的每一位是否都是在words数组中的
  // 注意:需要先判断是否存在,再判断长度是否需要计入
  for(let i = len - 1; i >= 0; i--) {
    let lenS = words[i].length;
    let str = '';
    for(let j = 0; j < lenS; j++) {
      str += words[i][j];
      if(words.indexOf(str) == -1) break;
      if(ans.length <= str.length) ans = str;
    }
  }
  return ans;
};

总结

  • 灵活应用sort函数,默认字母升序;若需要数值比较,需要自己书写函数。