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

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


8

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

题意:

给一组词,统计出现频率最高的 k 个。

比如说 “I love leetcode, I love coding” 中频率最高的 2 个就是 I 和 love 了。

有同学觉得这题特别简单,但其实这题只是母题,它可以升级到系统设计层面来问:

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

我们先看算法层面:

思路:

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

细节:

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

实现:

  1. 建一个 HashMap <key = 单词,value = 出现频率>,遍历整个数组,相应的把这个单词的出现次数 + 1.

这一步时间复杂度是 O(n).

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

    a. 首先按照出现的频率排序;

    b. 频率相同时,按字母顺序。
  2. 遍历这个 map,如果

    a. minHeap 里面的单词数还不到 k 个的时候就加进去;

    b. 或者遇到更高频的单词就把它替换掉。

时空复杂度分析:

第一步是 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 点,云自习室里不见不散!

更多干货文章见我的 Github: https://github.com/xiaoqi6666/NYCSDE

必考算法之 Top K 问题的更多相关文章

  1. 海量数据处理算法(top K问题)

    举例 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M.返回频数最高的100个词. 思路 首先把文件分开 针对每个文件hash遍历,统计每个词语的频率 使用堆进 ...

  2. Top K问题-BFPRT算法、Parition算法

    BFPRT算法原理 在BFPTR算法中,仅仅是改变了快速排序Partion中的pivot值的选取,在快速排序中,我们始终选择第一个元素或者最后一个元素作为pivot,而在BFPTR算法中,每次选择五分 ...

  3. 优先队列实现 大小根堆 解决top k 问题

      摘于:http://my.oschina.net/leejun2005/blog/135085 目录:[ - ] 1.认识 PriorityQueue 2.应用:求 Top K 大/小 的元素 3 ...

  4. Top k问题(线性时间选择算法)

    问题描述:给定n个整数,求其中第k小的数. 分析:显然,对所有的数据进行排序,即很容易找到第k小的数.但是排序的时间复杂度较高,很难达到线性时间,哈希排序可以实现,但是需要另外的辅助空间. 这里我提供 ...

  5. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

  6. Top K算法

    应用场景: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节.        假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但如果 ...

  7. 排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

    常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结 ...

  8. hihoCoder 1133 二分·二分查找之k小数(TOP K算法)

    #1133 : 二分·二分查找之k小数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上一回里我们知道Nettle在玩<艦これ>,Nettle的镇守府有很 ...

  9. 算法题解:最大或最小的K个数(海量数据Top K问题)

    题目 输入 n 个整数,找出其中最小的 k 个数.例如输入4.5.1.6.2.7.3.8 这8个数字,则最小的4个数字是1.2.3.4. 初窥 这道题最简单的思路莫过于把输入的 n 个整数排序,排序之 ...

随机推荐

  1. DB2根据报错代码查看表与字段信息

    select * from syscat.tables where tbspaceid='?' and tableid='?' select * from syscat.columns where t ...

  2. 转圈游戏C++

    转圈游戏 问题描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置, ...

  3. git 常规操作 windows版

    首先在本地建立好文件夹,然后初始化git仓库: git init 接下来在github上面克隆项目: git clone 这里写你的项目地址 然后就可以修改,删除,提交代码了  如果需要在新分支上面开 ...

  4. Federated Machine Learning: Concept and Applications

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Qiang Yang, Yang Liu, Tianjian Chen, and Yongxin Tong. 2019. Federate ...

  5. python 向excel 插入图片

    这是工作中一个真实的需求. 要做gt excel 表,表中要插入图片. 1.要把图片resize 基本相同的大小. 2.通过一下脚本插入图片到excel #!/usr/bin/env python3 ...

  6. pandas 数据表中的字符与日期数据的处理

    前面我们有学习过有关字符串的处理和正在表达式,但那都是基于单个字符串或字符串列表的操作.下面将学习如何基于数据框操作字符型变量. 同时介绍一下如何从日期型变量中取出年份,月份,星期几等,如何计算两个日 ...

  7. promise的常用情况

    因为js是单线程的,所以一旦代码中有报错,就不会执行下面的了,如下333就未打印 console.log(111)throw Error(222)console.log(333) 好像与promise ...

  8. Lombok 作者因兼容问题讨伐 IntelliJ IDEA(官方已妥协)

    今天(08/26),你看到本文应该是昨天了. 栈长上班打开电脑,按往常一样打开 IntelliJ IDEA 正准备撸码,突然收到 IDEA 2020.2.1 的更新提醒: 我现在用的还是 2020.1 ...

  9. C# 接口的Get、Post、WebService请求方法一览,值得收藏

    C# 接口的Get.Post.WebService请求方法一览,值得收藏 public static class HttpHelper { const string DEFAULT_USER_AGEN ...

  10. CCAI观后

    暑期和大老板的学生一起学了一暑假的计算机视觉和机器学习,以前只是在京畿范围的学校听到的报告和这阵的学习数量级都不同.当时看到了很多人的报告,忽然发现了做报告应该做的准备实际还有很多. 首先是要有充分的 ...