问题:输入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. ssm框架集成Quartz定时器

    第一步:添加依赖 <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>qu ...

  2. 设计模式中类的关系UML

    在java以及其他的面向对象设计模式中,类与类之间主要有6种关系,他们分别是:依赖.关联.聚合.组合.继承.实现.他们的耦合度依次增强. 1. 依赖(Dependence)  依赖关系的定义为:对于两 ...

  3. oracle入门(5)——java连接oracle数据库

    [本文介绍] 前面几篇说了那么多,最终还没讲到如何用java连接数据库,本文实用一点,讲讲如何连接数据库. [java连接oracle数据库] 1.导入jdbc驱动:看到这里,就忙着上网找驱动?不,安 ...

  4. MySQLdb使用批量插入executemany方法插入mysql

    python的MySQLdb库可以使用批量操作executemany,进行多行插入. 比如向user表(username,salt,pwd)插入数据,具体的sql语句如下: sql = 'INSERT ...

  5. 机器学习第2周---炼数成金-----线性回归与Logistic

    重点归纳 回归分析就是利用样本(已知数据),产生拟合方程,从而(对未知数据)迚行预测用途:预测,判别合理性例子:利用身高预测体重:利用广告费用预测商品销售额:等等.线性回归分析:一元线性:多元线性:广 ...

  6. Java io流详解四

    转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...

  7. ruby 修改Setting config yaml内容

    参考:http://ruby-doc.org/stdlib-1.9.3/libdoc/yaml/rdoc/YAML/Store.html 本事例只为说明如何修改yml文件内容. 一.需求是怎么样修改y ...

  8. modelform 使用

    modelForm (1) model的知识点: class UserInfo(AbstractUser): tel = models.CharField(max_length=32) gender ...

  9. testng失败截图,注解方式调用。

    今天一整天都在研究testng失败截图的方法,参考网上的前辈们的资料,加上自己的理解,终于搞出来了. package com.dengnapianhuahai; /** * 自定义注释 * */ im ...

  10. C++MFC之picture control控件铺满图片

    UpdateData(true); //更新路径公共变量     CString m_path = m_edit1.GetString();      if(m_path=="") ...