题目:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

package test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue; import org.junit.Test; public class GetLeastNumbers_Solution {
/**
* 基于优先队列,时间复杂度为o(nlogk)
*
* @param input
* @param k
* @return
*/
public ArrayList<Integer> GetLeastNumbers_SolutionPriorityQuene(
int[] input, int k) {
ArrayList<Integer> result = new ArrayList<Integer>();
if (input == null || input.length == 0 || k <= 0 || k > input.length)
return result;
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
for (int i = 0; i < k; i++) {
maxHeap.offer(input[i]);
}
for (int j = k; j < input.length; j++) {
if (input[j] < maxHeap.peek()) {
maxHeap.poll();
maxHeap.offer(input[j]);
}
}
for (Integer integer : maxHeap) {
result.add(integer);
} return result;
} /**
* 基于堆排序,时间复杂度为o(nlogk)
*
* @param input
* @param k
* @return
*/
public ArrayList<Integer> GetLeastNumbers_SolutionMaxHeap(int[] input, int k) {
ArrayList<Integer> result = new ArrayList<Integer>();
if (input == null || input.length == 0 || k <= 0 || k > input.length)
return result;
//构建最大堆
builtMaxHeap(input,k-1);
for (int i = k; i < input.length; i++) {
//数组k位后的数字比堆顶小
if (input[k] < input[0]) {
input[0] = input[k];
//调整堆
builtMaxHeap(input, k - 1);
}
}
for (int i = 0; i < k; i++) {
result.add(input[i]);
}
return result;
} /**
* 构建、调整最大堆
* @param a
* @param lastIndex
*/
public void builtMaxHeap(int[]a,int lastIndex){
int parentIndex = ((lastIndex-1) >> 1);
//从最后一个节点的父节点开始
for(int i=parentIndex;i>=0;i--){
//存在子节点
while (i*2+1<=lastIndex){
int leftIndex = i*2+1;
int rightIndex = i*2+2;
int biggerIndex = leftIndex;
//存在右结点
if (rightIndex <= lastIndex){
if(a[rightIndex] > a[biggerIndex]){
biggerIndex = rightIndex;
}
}
//子节点中最大节点大于父节点
if (a[biggerIndex] > a[i]){
swap(a,i,biggerIndex);
i = biggerIndex;
}else{
break;
}
}
}
} /**
* 基于Partition函数,时间复杂度为o(n),原数组已被修改
*
* @param input
* @param k
* @return
*/
public ArrayList<Integer> GetLeastNumbers_SolutionPartition(int[] input,
int k) {
ArrayList<Integer> result = new ArrayList<Integer>();
if (input == null || input.length == 0 || k <= 0 || k > input.length)
return result; int left = 0;
int right = input.length - 1;
int index = partition(input, 0, right); while (index != k - 1) {
if (index > k - 1) {
right = index - 1;
index = partition(input, left, right);
} else {
left = index + 1;
index = partition(input, left, right);
}
}
for (int i = 0; i < k; i++) {
result.add(input[i]);
} return result;
} /**
* partition函数
* @param a
* @param left
* @param right
* @return
*/
public int partition(int[] a, int left, int right) {
while (left < right) {
while (left < right && a[left] <= a[right]) {
right--;
}
if (left < right) {
swap(a, left, right);
}
while (left < right && a[left] <= a[right]) {
left++;
}
if (left < right) {
swap(a, left, right);
} }
return left;
} public void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
} @Test
public void testGetLeastNumbers_Solution() {
int[] a = { 4, 5, 1, 6, 2, 7, 3, 8 };
int k = 4;
ArrayList<Integer> list = GetLeastNumbers_SolutionPartition(a, k);
System.out.println(list.toString()); ArrayList<Integer> list2 = GetLeastNumbers_SolutionPriorityQuene(a, k);
System.out.println(list2.toString()); ArrayList<Integer> list3 = GetLeastNumbers_SolutionMaxHeap(a, k);
System.out.println(list3.toString()); }
}

除了基于优先队列,时间复杂度为O(nlogk)、堆排序,时间复杂度为O(nlogk)、partition函数,时间复杂度为O(n)的解法之外,还有基于冒泡排序的解法时间复杂度为(nk)

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

  1. 求一个数组中最小的K个数

    方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如 ...

  2. 【算法】数组与矩阵问题——找到无序数组中最小的k个数

    /** * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) * 过程: * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 * 在堆里的k个元素中堆顶的元素是最小的k个数 ...

  3. [算法]找到无序数组中最小的K个数

    题目: 给定一个无序的整型数组arr,找到其中最小的k个数. 方法一: 将数组排序,排序后的数组的前k个数就是最小的k个数. 时间复杂度:O(nlogn) 方法二: 时间复杂度:O(nlogk) 维护 ...

  4. 《程序员代码面试指南》第八章 数组和矩阵问题 找到无序数组中最小的k 个数

    题目 找到无序数组中最小的k 个数 java代码 package com.lizhouwei.chapter8; /** * @Description: 找到无序数组中最小的k 个数 * @Autho ...

  5. 小米笔试题:无序数组中最小的k个数

    题目描述 链接:https://www.nowcoder.com/questionTerminal/ec2575fb877d41c9a33d9bab2694ba47?source=relative 来 ...

  6. 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆

    原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...

  7. [剑指offer]数组中最小的K个数,C++实现

    原创博文,转载请注明出处! http://github.com/wanglei5205 http://cnblogs.com/wanglei5205 # 题目 输入n个整数,找出其中最小的K个数.例如 ...

  8. 找到数组中最小的k个数

    /*输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字, 则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = ...

  9. 面试题四十:数组中最小的k个数

    方法一:先排序后寻找前k个数: 方法二:受面试题三十九,寻找超过一半的数的启发,只把里面的middle改成k-1就行: void HalfNum( int [ ] Array ,int k){ int ...

随机推荐

  1. Js常用的函数

    1.用于对正则表达式的函数: var pattern=/\d{3}-\d{2}-\d{4}/;//这里产生的是一个object类型 alert(pattern.test("cscscscs& ...

  2. java定时器schedule和scheduleAtFixedRate区别

    package cn.lonecloud.test; import java.util.Date; import java.util.Timer; import java.util.TimerTask ...

  3. Qt ActiveX web dome 详细例子

    http://doc.qt.io/qt-5.9/activeqt-server.html hierarchy 例子 #ifndef OBJECTS_H #define OBJECTS_H #inclu ...

  4. c#IO的学习

    常见应用方面 一.路径的相关操作,如判定路径是否合法,路径类型,路径的特定部分,合并路径,系统文件夹路径等内容:二.相关通用文件对话框,这些对话框可以帮助我们操作文件系统中的文件和目录:三.文件.目录 ...

  5. Java NIO之缓冲区

    1.简介 Java NIO 相关类在 JDK 1.4 中被引入,用于提高 I/O 的效率.Java NIO 包含了很多东西,但核心的东西不外乎 Buffer.Channel 和 Selector.这其 ...

  6. android判断网络是否可用

    private boolean isNetworkConnected(Context context) { ConnectivityMannger cManager = (ConnectivityMa ...

  7. ARM架构

    ARM架构(过去称作进阶精简指令集机器(Advanced RISC Machine),更早称作Acorn RISC Machine)是一个32位元精简指令集(RISC) 中央处理器(processor ...

  8. FusionCharts 2D柱状图和折线图的组合图调试错误

    在设计FusionCharts 2D柱状图和折线图的组合图的时候,我发现不管怎么重启服务器,组合图就是不出来.后来,我通过调试发现我犯了一个致命的错误,运用平常一贯的思维,认为3D图有这种类型,那么2 ...

  9. 移动端web开发安卓和ios客户端在时间转换上的差异性问题

    作为一名移动前端开发的人员,平时遇到的兼容性问题不在少数.那么,今天就来说一下最近遇到的一个小坑(关于Android和ios在时间转换上的差异性问题)话不多说,直接上重点. 最近接到了一个需求,很简单 ...

  10. C#的动态链接库和XML配置

    今天对昨天的实例进行了改进和提高,将堆排序和冒泡排序封装在一个动态链接库中,提供函数调用和事件委托.此外加入XML进行配置,在XML中存入相关配置信息,提供一个单独的XmlClass对其进行操作,加深 ...