面试准备之--Top K算法的实现

本文介绍了求解数组中前K大元素的四种方法:排序、冒泡局部排序、堆排序和随机选择。详细讲解了每种方法的思路、伪代码和时间复杂度,重点分析了堆和随机选择算法在求TopK上的优势。
摘要由CSDN通过智能技术生成

1. 问题描述

给定一个数字数组,求其中前K大的数字

2. 解题思路

https://blog.csdn.net/u013132035/article/details/82936032

  • 快排—将所有数据排序,返回其中前K大的数字
  • 冒泡—局部排序;冒K次泡,就把最大的K个数都冒上来
  • 堆排序 — 维护一个容量为k的堆保存topk的数组,然后对每个数字比较一遍。思路也很简单,复杂度是O(nlogn)

方法一:排序

排序是最容易想到的方法,将n个数排序之后,取出最大的k个,即为所得。
在这里插入图片描述
伪代码:

sort(arr, 1, n);
return arr[1, k];

时间复杂度:O(n*lg(n))

分析:明明只需要TopK,却将全局都排序了,这也是这个方法复杂度非常高的原因。那能不能不全局排序,而只局部排序呢?这就引出了第二个优化方法。

方法二:冒泡–局部排序

不再全局排序,只对最大的k个排序。
冒泡是一个很常见的排序方法,每冒一个泡,找出最大值,冒k个泡,就得到TopK。
在这里插入图片描述
伪代码:

for(i=1 to k){
   
    bubble_find_max(arr,i);
}
return arr[1, k];

时间复杂度:O(n*k)

分析:冒泡,将全局排序优化为了局部排序,非TopK的元素是不需要排序的,节省了计算资源。不少朋友会想到,需求是TopK,是不是这最大的k个元素也不需要排序呢?这就引出了第三个优化方法。

方法三: 堆

思路:只找到TopK,不排序TopK。

  1. 先用前k个元素生成一个小顶堆,这个小顶堆用于存储,当前最大的k个元素。
    在这里插入图片描述
  2. 接着,从第k+1个元素开始扫描,和堆顶(堆中最小的元素)比较,如果被扫描的元素大于堆顶,则替换堆顶的元素,并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。
    在这里插入图片描述
  3. 直到,扫描完所有n-k个元素,最终堆中的k个元素,就是求的TopK。
    在这里插入图片描述
    伪代码:

heap[k] = make_heap(arr[1, k]);
for(i=k+1 to n){
   
    adjust_heap(heep[k],arr[i]);
}
return heap[k];

Java代码


public class TopK {
   
  /**
   * 创建k个节点的小根堆
   * 
   * @param a
   * @param k
   * @return
   */
  int[] createHeap(int a[], int k) {
   
    int[] result = new int[k];
    for (int i = 0; i < k; i++) {
   
      result[i] = a[i];
    }
    for (int i = 1; i <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值