问题:输入n个整数,找出其中最小的k个数。

方案一:将输入的n个整数进行排序,输出前k个数即为所求的k个最小数。时间复杂度为O(nlogn).

方案二:创建一个大小为k的容器,来存储最小的k个数。遍历剩下的n-k个数字,如果大于k个数中的最大值,则替换;否则继续遍历数组的剩  下的数字。

  在装k个最小数字的容器(使用大根堆)中,所要做的操作有以下三个:

  (1)在k个整数中找到最大的值;(时间复杂度为O(1),根节点即为最大值点)

  (2)在这个容器中删除最大的数字;

  (3)将可能要插入的值插入到容器中。(插入和删除的时间复杂度为O(logk))

总共有n个节点,则总的时间复杂度为O(nlogk)。

package com.wyl;
/**
* 找到数组中的k个最小值
* @author wyl
*/
public class KMin {
/**
* 找到数组array中最下的k个数
* 思路:将数组的前K个数当作最小的k个数,存入到数组2中,
* 遍历array中剩余的n-k个数,如果比数组2中的最大数字小,替换数组2中的数字;
* 比其大继续遍历,最后数组2中存放的即为最小的k个数
* @param array
* @param k
* @return
*/
public void findKMin(int[] array, int k){
if(array.length < k){
return;
}
int[] newArray = new int[k];
for(int i=0;i<k;i++){ //前k个数字存入数组中
newArray[i] = array[i];
}
//将数组调整成大根堆,k/2为堆的最后一个非叶节点
for(int i = k/2 - 1;i>=0;i--){
//最后一个非叶节点的下标为n/2-1
rebuildHeap(newArray, i, k);
} //n-k个数和前面和k中最大数比较
for (int i =k; i < array.length; i++) {
//如果堆顶大于n-k中数,则交换位置
if(newArray[0]>array[i]){
newArray[0]=array[i];
//调整堆,堆顶被替换了,加入被替换的值非常小,会一直下沉到叶子节点.
for(int j = k/2 - 1;j>=0;j--){
//最后一个非叶节点的下标为n/2-1
rebuildHeap(newArray, j, k);
}
} }
// 输出最小的K个数
for (int i = 0; i < k; i++) {
System.out.print(newArray[i] + " ");
}
}
/**
* 调整堆
* @param a
* @param i
* @param n
*/
public void rebuildHeap(int[] a, int i, int n){
if(n <= 0){
return;
}
int temp = a[i]; //待调整节点
boolean finish = false; //调整完成标志
int li = 2 * i + 1; //左节点下标
while(li <= n - 1 && !finish){
if(li < n - 1 && a[li] < a[li+1]){ //节点存在右子树,且右子树值大于左子树
li = li+1;
}
if(temp < a[li]){ //待调整节点值小于子树值,继续调整子树
a[i] = a[li];
a[li] = temp;
}else{
finish = true;
}
}
} public static void main(String[] args) {
KMin kMin = new KMin();
int[] array = {4,5,1,6,3,8,7,9};
kMin.findKMin(array, 4);
}
}

  

数组中的k个最小值的更多相关文章

  1. 前端算法题:找出数组中第k大的数字出现多少次

    题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...

  2. [LeetCode] Kth Largest Element in an Array 数组中第k大的数字

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  3. 如何使用Math对象快速计算数组中的最大值或最小值

    Math 对象下包含 min() 和 max() 方法 用于确定一组数值中的最大值和最小值.这两个方法都可以接收任意多个数值参数. var max = Math.max(1,2,3,4,5,6); c ...

  4. 数组中第K小的数字(Google面试题)

    http://ac.jobdu.com/problem.php?pid=1534 题目1534:数组中第K小的数字 时间限制:2 秒 内存限制:128 兆 特殊判题:否 提交:1120 解决:208 ...

  5. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  6. C#获取一个数组中的最大值、最小值、平均值

    C#获取一个数组中的最大值.最小值.平均值 1.给出一个数组 ,,,,,-,,,,}; 2.数组Array自带方法 本身是直接可以调用Min(),Max(),Average()方法来求出 最小值.最大 ...

  7. Javascript获取数组中的最大值和最小值的方法汇总

    比较数组中数值的大小是比较常见的操作,下面同本文给大家分享四种放哪广发获取数组中最大值和最小值,对此感兴趣的朋友一起学习吧   比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用 ...

  8. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  9. 选择问题(选择数组中第K小的数)

    由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小 ...

随机推荐

  1. 跨域问题session不一致问题的解决(前端和后台在不同的服务器)

    场景:首先调用发送短信接口,然后调用注册接口,结果后台的session不一致获取不到之前验证码. 实质:每次ajax跨域访问都是新的session ,每次的sessionID都不一样 解决: pack ...

  2. 深入浅出java IO模型

    一.同步和异步 同步:一个事件或者任务的执行,会使整个流程暂时等待,也就是说如果有多个任务要执行,必须要逐个进行. 异步:一个事件或者任务的执行,不会使整个流程暂时等待,也就是说如果有多个任务要执行, ...

  3. git获取远程仓库代码

    首先在本地创建一个目录“ MyProject”,用来存放工程文件,git进入该文件夹,执行 git clone 远程项目MyCode地址 将代码克隆到本地然后进入“MyCode”文件夹下 cd MyC ...

  4. linxu系统压缩解压命令

    使用cat命令进行文件的纵向合并 两种文件的纵向合并方法 归档文件和归档技术 归档的目的 什么是归档 tar命令的功能 tar命令的常用选项 使用tar命令创建.查看及抽取归档文件 使用tar命令创建 ...

  5. execute sp_executesql 用变量获取返回值

    execute sp_executesql 用变量获取返回值 1,EXEC的使用 2,sp_executesql的使用 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_exe ...

  6. android 自定义View 对话框

    package com.example.dialog5; import android.os.Bundle;import android.app.Activity;import android.app ...

  7. Linux系统——系统安全及应用

    系统账号清理 将非登录用户的shell设为/sbin/nologin 方法一:usermod -s 方法二: chsh命令,交互式修改,用来修改用户的登录情况 方法三: chsh -s 方法四:vim ...

  8. nginx 413文件上报太大

    在nginx使用过程中,上传文件的过程中,通常需要设置nginx报文大小限制.避免出现413 Request Entity Too Large. 于是奇葩的问题被我们遇到了,详细配置请参考下面.我们的 ...

  9. java知识框架

    从网上摘录的一张很经典的java学习框架图,和大家分享一下.

  10. vue工程权限怎么配置?

    vue工程权限怎么配置? router.beforeEach((to, from, next) => { }):方法的to参数能拿到router设置的对象信息,如: { path: " ...