剑指:最小的k个数
2024-08-24 12:53:17
题目描述
输入 n 个整数,找出其中最小的 K 个数。例如输入 4,5,1,6,2,7,3,8
这 8 个数字,则最小的 4 个数字是 1,2,3,4
。
解法
解法一
利用快排中的 partition 思想。
数组中有一个数字出现次数超过了数组长度的一半,那么排序后,数组中间的数字一定就是我们要找的数字。我们随机选一个数字,利用 partition() 函数,使得比选中数字小的数字都排在它左边,比选中数字大的数字都排在它的右边。
判断选中数字的下标 index
:
- 如果
index = k-1
,结束循环,返回前 k 个数。 - 如果
index > k-1
,那么接着在 index 的左边进行 partition。 - 如果
index < k-1
,则在 index 的右边继续进行 partition。
注意,这种方法会修改输入的数组。时间复杂度为 O(n)
。
public class Solution { public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k){
ArrayList<Integer> res = new ArrayList<>();
if(input==null || input.length==0||input.length<k||k<1){
return null;
}
int n= input.length;
int start=0;
int end = n-1;
int p = partition(input, start, end);
while(p != k-1){
if(p>k-1){
end = p-1;
}else{
start = p+1;
}
p = partition(input, start, end);
}
for(int i=0; i<k; i++){
res.add(input[i]);
}
return res;
} private static int partition(int[] arr, int start, int end) {
int p = arr[start];
while(start<end){
while(start<end && arr[end]>=p) end--;
arr[start] = arr[end];
while(start<end && arr[start]<=p) start++;
arr[end] = arr[start];
}
arr[start] = p;
return start;
} public static void main(String[] args) {
int[] arr = {1,2,9,3,0,8,7,5,6,4};
int k = 5;
ArrayList nums = GetLeastNumbers_Solution(arr, k);
for(int i=0;i<nums.size();i++){
System.out.println(nums.get(i));
}
}
}
解法二
利用大根堆,存储最小的 k 个数,最后返回即可。
此方法时间复杂度为 O(nlogk)
。虽然慢一点,但是它不会改变输入的数组,并且它适合海量数据的输入。
假设题目要求从海量的数据中找出最小的 k 个数,由于内存的大小是有限的,有可能不能把这些海量的数据一次性全部载入内存。这个时候,用这种方法是最合适的。就是说它适合 n 很大并且 k 较小的问题。
public class Solution { public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k){
ArrayList<Integer> res = new ArrayList<>();
if(input==null || input.length==0||input.length<k||k<1){
return null;
} PriorityQueue<Integer> maxHeap = new PriorityQueue<>(k, Comparator.reverseOrder());
System.out.println("maxHeap_size:" + maxHeap.size());
for (int e : input) {
if (maxHeap.size() < k) {
maxHeap.add(e);
} else {
if (maxHeap.peek() > e) {
maxHeap.poll();
maxHeap.add(e);
}
}
}
res.addAll(maxHeap);
return res;
} public static void main(String[] args) {
int[] arr = {1,2,9,3,0,8,7,5,6,4};
int k = 4;
ArrayList nums = GetLeastNumbers_Solution(arr, k);
for(int i=0;i<nums.size();i++){
System.out.println(nums.get(i));
}
}
}
最新文章
- 例解 Linux cd 命令
- wordpress 自定义登录表单
- LINQ的Expression与delegate表达式
- JS添加删除DIV
- Linux读写锁的使用
- lintcode :Longest Palindromic Substring 最长回文子串
- bzoj1570
- FastDFS 的部署、配置与测试的
- jsp页面 使用c 标签的 varStatus 属性和 index 解决一行显示多少个 然后进行自动换行
- JSBridge(Android和IOS平台)的设计和实现
- Swift利用闭包(closure)来实现传值-->;前后两个控制器的反向传值
- Python基础知识学习_Day4
- php数组的使用
- nodejs+express-实现文件上传下载管理的网站
- Nginx的知识分享,感兴趣的可以看一下
- android拍照获得图片及获得图片后剪切设置到ImageView
- python学习第26天
- vue_简介_渐进式 js 框架_内置指令_自定义指令_自定义插件
- 关于“svn: Can&#39;t connect to host &#39;*.*.*.*&#39;: 由于连接方在一段时间后没有正确答复或连接”的解决方法
- ubuntu下openssh升级
热门文章
- 莫烦TensorFlow_02 Session的两种方法
- nginx 缓存配置
- Git分支的介绍及Gitlab的部署
- MySQL实战45讲学习笔记:第九讲
- [LeetCode] 406. Queue Reconstruction by Height 根据高度重建队列
- 【微信小程序】 小程序中的递归运算/二分查找算法/Maximum call stack size exceeded
- Salesforce Lightning开发学习(四)重写新建/更新按钮
- TJOI 2015 概率论(生成函数)
- Java 并发系列之八:java 并发工具(4个)
- JAVA主动抛异常的几种方式及捕捉结果输出对比