必考算法之 Top K 问题

简介: 大家好,这里是《齐姐聊算法》系列之 Top K 问题。

Top K 问题是面试中非常常考的算法题。


image.png


Leetcode 上这两题大同小异,这里以第一题为例。


image.png


题意:给一组词,统计出现频率最高的 k 个。比如说 “I love leetcode, I love coding” 中频率最高的 2 个就是 I 和 love 了。


有同学觉得这题特别简单,但其实这题只是母题,它可以升级到<span style="color:blue;font-weight:bold;">系统设计</span>层面来问:


在某电商网站上,过去的一小时内卖出的最多的 k 种货物。


我们先看算法层面:


<span style="color:orangered;font-weight:bold;">思路:


统计下所有词的频率,然后按频率排序取最高的前 k 个呗。


<span style="color:orangered;font-weight:bold;">细节:


用 HashMap 存放单词的频率,用 minHeap/maxHeap 来取前 k 个。


<span style="color:orangered;font-weight:bold;">实现:


  1. 建一个 HashMap <key = 单词,value = 出现频率>,遍历整个数组,相应的把这个单词的出现次数 + 1.这一步时间复杂度是 O(n).


  1. 用 size = k 的 minHeap 来存放结果,定义好题目中规定的比较顺序


a. 首先按照出现的频率排序;
b. 频率相同时,按字母顺序。


  1. 遍历这个 map,如果


a. minHeap 里面的单词数还不到 k 个的时候就加进去;
b. 或者遇到更高频的单词就把它替换掉。


<span style="color:orangered;font-weight:bold;">时空复杂度分析:


第一步是 O(n),第三步是 nlog(k),所以加在一起时间复杂度是 O(nlogk).


用了一个额外的 heap 和 map,空间复杂度是 O(n).


代码:


class Solution {
    public List<String> topKFrequent(String[] words, int k) {
        // Step 1
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            Integer count = map.getOrDefault(word, 0);
            count++;
            map.put(word, count);
        }
        // Step 2
        PriorityQueue<Map.Entry<String, Integer>> minHeap = new PriorityQueue<>(k+1, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
                if(e1.getValue() == e2.getValue()) {
                    return e2.getKey().compareTo(e1.getKey());
                }
                return e1.getValue().compareTo(e2.getValue());
            }
        });
        // Step 3
        List<String> res = new ArrayList<>();
        for(Map.Entry<String, Integer> entry : map.entrySet()) {
            minHeap.offer(entry);
            if(minHeap.size() > k) {
                minHeap.poll();
            }
        }
        while(!minHeap.isEmpty()) {
            res.add(minHeap.poll().getKey());
        }
        Collections.reverse(res);
        return res;
    }
}


如果你喜欢这篇文章,记得给我点赞留言哦~你们的支持和认可,就是我创作的最大动力,我们下篇文章见!


我是小齐,纽约程序媛,终生学习者,每天晚上 9 点,云自习室里不见不散!

目录
相关文章
|
8月前
|
算法
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
【经典LeetCode算法题目专栏分类】【第10期】排序问题、股票问题与TOP K问题:翻转对、买卖股票最佳时机、数组中第K个最大/最小元素
|
9月前
|
存储 机器学习/深度学习 算法
数据结构与算法⑬(第四章_中_续二)堆解决Topk问题+堆的概念选择题
数据结构与算法⑬(第四章_中_续二)堆解决Topk问题+堆的概念选择题
73 3
|
9月前
|
算法 C++
算法--topk问题
该文介绍了TopK问题的两种解决方案:大小根堆和快排分割。使用大根堆可以找到前K小的元素,小根堆则用于找到前K大的元素。示例代码展示了如何用C++实现这两个方法。快排分割通过不断调整数组结构,找到第K大或第K小的元素。文章提供了相应的代码示例及输出结果。
52 0
|
9月前
|
算法
堆排序+TopK问题——“数据结构与算法”
堆排序+TopK问题——“数据结构与算法”
|
存储 算法 数据处理
提高数据处理效率的有力工具:TopK算法解析
提高数据处理效率的有力工具:TopK算法解析
280 0
提高数据处理效率的有力工具:TopK算法解析
|
算法 搜索推荐
最优商品topk排名算法
最优商品topk排名算法
105 0
|
算法
【数据结构与算法】堆的应用:堆排序和topk问题
【数据结构与算法】堆的应用:堆排序和topk问题
91 0
|
分布式计算 算法 搜索推荐
【经典算法问题 一】海量数据中找出前k大数(topk问题)
【经典算法问题 一】海量数据中找出前k大数(topk问题)
239 0
|
算法 程序员 C语言
一篇解建堆,堆的实现,堆排序,TopK问题(C语言)《数据结构与算法》
一篇解建堆,堆的实现,堆排序,TopK问题(C语言)《数据结构与算法》
一篇解建堆,堆的实现,堆排序,TopK问题(C语言)《数据结构与算法》
|
算法
算法给小码农TopK重瞳双目
算法给小码农TopK重瞳双目
141 0

热门文章

最新文章