问题:输入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. springMvc异常之 For input string: "show"

    异常提示: For input string: "show" 异常原因: 使用@PathVariable方式获取值,返回类型为String return "redirec ...

  2. (3.9)常用知识-标识值(identity)的不连续与强行插入、计算列

    概念:标识值 identity(begin,add_number) 是一种特殊的值,依赖于列,由sql server自动维护,是自增的,而且一般是不会重复的.但是sql server并不维护标识(id ...

  3. Windows服务的安装、卸载

    创建一个Windows服务 http://jingyan.baidu.com/article/fa4125acb71a8628ac709226.html 安装服务 使用FramWork框架自带的Ins ...

  4. PAT 1063 Set Similarity[比较]

    1063 Set Similarity (25 分) Given two sets of integers, the similarity of the sets is defined to be N ...

  5. JVM之参数分配详解

    开篇之前,推荐一个关于JVM很不错的博客:http://www.cnblogs.com/redcreen/archive/2011/05/04/2036387.html 一.堆参数设置 -XX:+Pr ...

  6. 自己动手写RNN

    说的再好,也不如实际行动,今天手写了一个RNN,没有使用Numpy库,自己写的矩阵运算方法,由于这也只是个学习用的demo,所以矩阵运算那一部分写的比较丑陋,见笑了. import com.mylea ...

  7. Oracle 性能调优 SQL_TRACE

    思维导图 Oracle优化10-SQL_TRACE解读 Oracle优化11-10046事件 概述 当我们想了解一条SQL或者是PL/SQL包的运行情况时,特别是当他们的性能非常差时,比如有的时候看起 ...

  8. java通过URL获取文本内容

    原文地址https://www.cnblogs.com/myadmin/p/7634262.html public static String readFileByUrl(String urlStr) ...

  9. windows安装oracle client 18c 和plsql工具

    安装须知: (1)安装平台选择.linux/windows (2)软件位数选择.32/64,如果你的plsql工具是32位,那么你就安装32位客户端,如果是64位,你就安装64位客户端. 安装过程: ...

  10. PKU 2082 Terrible Sets(单调栈)

    题目大意:原题链接 一排紧密相连的矩形,求能构成的最大矩形面积. 为了防止栈为空,所以提前加入元素(0,0). #include<cstdio> #include<stack> ...