题目描述

输入 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));
}
}
}

剑指:最小的k个数的更多相关文章

  1. 【Java】 剑指offer(40) 最小的k个数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7 ...

  2. 剑指offer 最小的k个数 、 leetcode 215. Kth Largest Element in an Array 、295. Find Median from Data Stream(剑指 数据流中位数)

    注意multiset的一个bug: multiset带一个参数的erase函数原型有两种.一是传递一个元素值,如上面例子代码中,这时候删除的是集合中所有值等于输入值的元素,并且返回删除的元素个数:另外 ...

  3. 剑指Offer - 九度1371 - 最小的K个数

    剑指Offer - 九度1371 - 最小的K个数2013-11-23 15:45 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是 ...

  4. 【剑指Offer面试题】 九度OJ1371:最小的K个数

    题目链接地址: http://ac.jobdu.com/problem.php?pid=1371 题目1371:最小的K个数 时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265 ...

  5. 剑指Offer(二十九):最小的K个数

    剑指Offer(二十九):最小的K个数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...

  6. Go语言实现:【剑指offer】最小的K个数

    该题目来源于牛客网<剑指offer>专题. 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. Go语言实现: fu ...

  7. 【剑指Offer面试编程题】题目1371:最小的K个数--九度OJ

    题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1< ...

  8. 剑指 Offer 40. 最小的k个数 + 优先队列 + 堆 + 快速排序

    剑指 Offer 40. 最小的k个数 Offer_40 题目描述 解法一:排序后取前k个数 /** * 题目描述:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7. ...

  9. 剑指 Offer 40. 最小的k个数

    剑指 Offer 40. 最小的k个数 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:ar ...

  10. 最小的K个数 牛客网 剑指Offer

    最小的K个数 牛客网 剑指Offer 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. class Solution ...

随机推荐

  1. webpy安装

    C:\Users\ceshi>python -m pip install web.pyCollecting web.py Downloading web.py-0.38.tar.gz (91kB ...

  2. 【使用篇二】SpringBoot访问静态资源(4)

    默认的,SpringBoot会从两个地方查找静态资源: classpath/static 的目录下 ServletContext 根目录下 一.classpath/static 的目录 在类路径下常见 ...

  3. <Array> 274 275

    274. H-Index 这道题让我们求H指数,这个质数是用来衡量研究人员的学术水平的质数,定义为一个人的学术文章有n篇分别被引用了n次,那么H指数就是n. 用桶排序,按引用数从后往前计算论文数量,当 ...

  4. [LeetCode] 381. Insert Delete GetRandom O(1) - Duplicates allowed 常数时间内插入删除和获得随机数 - 允许重复

    Design a data structure that supports all following operations in average O(1) time. Note: Duplicate ...

  5. wifidog 用户第一次访问网络流程图

    通过wifidog实现用户上网强制认证后,用户第一次访问网络的流程大致如下: 1.用户通过浏览器访问某一网页. 2.wifidog重定向用户请求到认证服务器. 3.认证服务器返回登录认证页面给用户. ...

  6. UDF——处理二维网格的利器:Boost.Geometry库

    本文编译工具:VC++ UDF Studio 该插件可以直接在Visual Studio中一键编译.加载.调试UDF源码,极大提高编写排错效率,且支持C++,MFC,Windows API和第三方库, ...

  7. java byte[]和base64互相转换

      1.方式一 import java.io.UnsupportedEncodingException; import java.util.Base64; // byte[]转base64 Strin ...

  8. Ubuntu 14.04 apt-get update失效解决(转)

    现象如下: VirtualBox:~$ sudo apt-get update Err http://mirrors.aliyun.com trusty InRelease Err http://mi ...

  9. Django 数据库同步命令

    版本1.8.2 检查数据库配置是否有错 Python manage.py validate/check 创建对应书看的映射语句 Python manage.py makemigrations 同步或者 ...

  10. Elasticsearch由浅入深(四)ES并发冲突、悲观锁与乐观锁、_version乐观锁并发

    ES并发冲突 举个例子,比如是电商场景下,假设说,我们有个程序,工作的流程是这样子的: 读取商品信息(包含了商品库存) 用户下单购买 更新商品信息(主要是将库存减1) 我们比如咱们的程序就是多线程的, ...