最小的 K 个数
2023-04-18 12:56:57 时间
题目描述
描述 给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。 数据范围:0≤k,n≤10000,数组中每个数的大小0 ≤val≤1000 要求:空间复杂度 O(n) ,时间复杂度 O(nlogn)
输入:
[4,5,1,6,2,7,3,8],4
返回值:
[1,2,3,4]
说明: 返回最小的4个数即可,返回[1,3,2,4]也可以
解题思路
大小为 K 的最小堆
- 时间复杂度:O(NlogK)
- 空间复杂度:O(K)
- 特别适合处理海量数据 维护一个大小为 K 的最小堆过程如下:使用大顶堆。在添加一个元素之后,如果大顶堆的大小大于 K,那么将大顶堆的堆顶元素去除,也就是将当前堆中值最大的元素去除,从而使得留在堆中的元素都比被去除的元素来得小。
应该使用大顶堆来维护最小堆,而不能直接创建一个小顶堆并设置一个大小,企图让小顶堆中的元素都是最小元素。
Java 的 PriorityQueue 实现了堆的能力,PriorityQueue 默认是小顶堆,可以在在初始化时使用 Lambda 表达式 (o1, o2) -> o2 - o1 来实现大顶堆。其它语言也有类似的堆数据结构。
public class Topk {
public static void main(String[] args) {
int[] nums = {4,5,1,6,2,7,3,8};
List<Integer> leastNumber = new Topk().getLeastNumber(nums, 4);
System.out.println(leastNumber);
}
public List<Integer> getLeastNumber(int[] nums, int k) {
if (k > nums.length || k <= 0)
return new ArrayList<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1);
for (int num : nums) {
maxHeap.add(num);
if (maxHeap.size() > k)
maxHeap.poll();
}
return new ArrayList<>(maxHeap);
}
}
相关文章
- 为什么 Linux 和 MacOS 不需要碎片整理
- Firefox 89 Beta 发布:全新现代 UI,精简菜单、增强隐私 / 安全
- Windows 10 v1909 即将结束服务,微软推出可靠性补丁更新
- 多台Windows10系统电脑,如何才能共享打印机,学会这招就能共享打印
- Spark:利用Eclipse构建Spark集成开发环境
- 利用Scala语言开发Spark应用程序
- Hi3861_WiFi IoT工程的一点理解
- 大数据处理利器:Hadoop具有五大优势
- 明尼苏达被Linux 拉黑?华人教授发公开信称补丁没有危害,GKH:不讲武德
- 使用Windows10系统电脑,怎么才能保证电脑安全,来学学怎么设置密码
- 索尼将为 Linux 带来设备内存不足的解决方案
- Windows 10禁用IP Helper优化电脑网络速度
- 移植Linux:如何制作rootfs?详细教程
- Fedora Linux 中有 Bug 吗?一起来修复它!
- 膜拜大神!Linux之父家中停电6天,竟然还码出新版Linux内核还是来了
- Facebook数据专家:处理大数据,仅有Hadoop不够
- 使用Windows 10x操作系统,怎么才能玩Windows 7游戏?仅需简单设置即可
- Windows软件包管理器迎来v0.3预览版更新
- Windows 10推送四月份更新,修复此前的Bug,同时带来了新的问题
- Windows 10电脑操作系统,扬声器没声音了怎么办,看大神是怎么操作的