LeetCode 算法:前K个高频单词

95 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 15 天,点击查看活动详情

前K个高频单词

原题地址

给定一个单词列表 words 和一个整数 k ,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率, 按字典顺序 排序

示例 1:

输入: words = ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i""love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i""love" 之前。

示例 2:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny""day" 是出现次数最多的四个单词,
    出现次数依次为 4, 3, 21 次。

注意:

  • 1 <= words.length <= 500
  • 1 <= words[i] <= 10
  • words[i] 由小写英文字母组成。
  • k 的取值范围是 [1, 不同 words[i] 的数量]  

进阶:

  • 尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。

思路分析

  1. 首先使用 map 来存储 words 中每个单词出现的次数,以 words[i]key,次数为 value 来存储;
  2. 得到 map 后,可以先针对 map 中的 key 进行排序,然后再按照 value 进行排序;
  3. 最后取数组的前 k 项即可。

注意:

  1. 初始没有 get 到题目中字典顺序是什么意思,以为 words 就是给出的字典,于是没有按照首字母的 ASCII 码排序,在运行测试用例时肯定是有误的;
  2. 在比较字符串大小时,因为 sort 默认是按照 ASCII 码进行排序的,所以可以直接使用,但是如果要降序的话,可以使用 localeCompare 来比较。

AC 代码

/**
 * @param {string[]} words
 * @param {number} k
 * @return {string[]}
 */
var topKFrequent = function(words, k) {
    const map = {}
    for(let i = 0; i < words.length; i++) {
        const word = words[i]
        if(map[word]) {
            map[word] += 1
        } else {
            map[word] = 1
        }
    }
    const maps = Object.keys(map).sort().sort((key1, key2) => map[key2] - map[key1])
    return maps.splice(0, k)
};

结果:

  • 执行结果: 通过
  • 执行用时:80 ms, 在所有 JavaScript 提交中击败了50.48%的用户
  • 内存消耗:43.5 MB, 在所有 JavaScript 提交中击败了87.32%的用户
  • 通过测试用例:110 / 110

END