求数组中最小的k个数
题目:输入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个数的更多相关文章
- 求一个数组中最小的K个数
方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如 ...
- 【算法】数组与矩阵问题——找到无序数组中最小的k个数
/** * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) * 过程: * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 * 在堆里的k个元素中堆顶的元素是最小的k个数 ...
- [算法]找到无序数组中最小的K个数
题目: 给定一个无序的整型数组arr,找到其中最小的k个数. 方法一: 将数组排序,排序后的数组的前k个数就是最小的k个数. 时间复杂度:O(nlogn) 方法二: 时间复杂度:O(nlogk) 维护 ...
- 《程序员代码面试指南》第八章 数组和矩阵问题 找到无序数组中最小的k 个数
题目 找到无序数组中最小的k 个数 java代码 package com.lizhouwei.chapter8; /** * @Description: 找到无序数组中最小的k 个数 * @Autho ...
- 小米笔试题:无序数组中最小的k个数
题目描述 链接:https://www.nowcoder.com/questionTerminal/ec2575fb877d41c9a33d9bab2694ba47?source=relative 来 ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- [剑指offer]数组中最小的K个数,C++实现
原创博文,转载请注明出处! http://github.com/wanglei5205 http://cnblogs.com/wanglei5205 # 题目 输入n个整数,找出其中最小的K个数.例如 ...
- 找到数组中最小的k个数
/*输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字, 则最小的4个数字是1.2.3.4. 示例 1: 输入:arr = [3,2,1], k = ...
- 面试题四十:数组中最小的k个数
方法一:先排序后寻找前k个数: 方法二:受面试题三十九,寻找超过一半的数的启发,只把里面的middle改成k-1就行: void HalfNum( int [ ] Array ,int k){ int ...
随机推荐
- J2ee的13个规范
以下来自于网络. 1.JDBC(java Database Connectivity): JDBC API为访问不同的数据库提供了一种统一的途径,就像ODBC一样,JDBC对开发者屏蔽了一些细节问题, ...
- PHP判断是手机端还是PC端
function check_wap() { if (isset($_SERVER['HTTP_VIA'])) return true; if (isset($_SERVER['HTTP_X_NOKI ...
- Flask從入門到入土(三)——模板
模板是一個包含響應文本的文件,其中包含佔位變量表示的動態部分,其具體值只是請求上下文中才能知道.使用真實值替換變量,再返回最終得到的響應字符串,這一過程稱爲渲染.爲了渲染模板,Flask使用了一個名爲 ...
- Python——文件操作详解
python中对文件.文件夹(文件操作函数)的操作需要涉及到os模块和shutil模块. 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目 ...
- Java集合框架(二)—— HashSet、LinkedHashSet、TreeSet和EnumSet
Set接口 前面已经简绍过Set集合,它类似于一个罐子,一旦把对象'丢进'Set集合,集合里多个对象之间没有明显的顺序.Set集合与Collection基本上完全一样,它没有提供任何额外的方法. Se ...
- # *Qt for Com 交互*
Qt COM Q_PROPERTY ActiveX properties public slots ActiveX methods signals ActiveX events Qt 属性支持的数据类 ...
- hdu1242 Rescue bfs+优先队列
直接把Angle的位置作为起点,广度优先搜索即可,这题不是步数最少,而是time最少,就把以time作为衡量标准,加入优先队列,队首就是当前time最少的.遇到Angle的朋友就退出.只需15ms A ...
- 实战项目:EMOS集成邮件平台
实战项目:EMOS集成邮件平台用户邮箱系统:http://mailAnonymous.cn/邮件服务器管理平台http://mailAnonymous.cn/extman 项目需求:随着公司规模不断扩 ...
- Hibernate入门这一篇就够了
前言 本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门,相信你们看了就会使用Hibernate了! 什么是Hibernate框架? Hibernate是一种ORM框架,全 ...
- PHPmysqli的 其他函数 从数据库中读出数据并且打印出来
<?php // 认识其他mysqli其他函数 header( 'Content-Type:text/html;charset=utf-8 '); require 'prepareSrarmen ...