1. 最小的K个数

题目描述

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

思路

Java 中的PriorityQueue是一个基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。优先级队列不允许使用 null 元素。依靠自然顺序的优先级队列还不允许插入不可比较的对象(这样做可能导致 ClassCastException)。

此队列的头是按指定排序方式确定的最小元素。如果多个元素都是最小值,则头是其中一个元素——选择方法是任意的。队列获取操作 poll、 remove、peek 和 element 访问处于队列头的元素。

关于PriorityQueue的更多介绍可以查看:https://blog.csdn.net/x_i_y_u_e/article/details/46381481

关于采用PriorityQueue实现最大堆和最小堆,可以参考:http://www.cnblogs.com/yongh/p/9945539.html

https://www.cnblogs.com/Elliott-Su-Faith-change-our-life/p/7472265.html

选择最小的k个数可以用冒泡排序,复杂度为O(n*k),有点高。最经典的方法是使用最大堆,每次取数与堆顶的元素进行比较,如果堆顶元素大,则删除堆顶元素,并添加这个新数到堆中。

Java没有堆的实现,现场写也来不及,有的文献说用TreeSet,比如剑指offer,但是TreeSet是一个set,相同的数只能存一个,相比之下,Java中的PriorityQueue倒是一个不错的选择。

代码

通过PriorityQueue写法:

import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
if (input == null || k <= 0 || k > input.length) {
return new ArrayList<Integer>();
}
Queue<Integer> queue = new PriorityQueue<>(k, new Comparator<Integer>() {
//降序
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for (int i = 0; i < input.length; i++) {
if(queue.size() == k){
if(queue.peek() > input[i]){
queue.poll();
queue.add(input[i]);
}
}else{
queue.add(input[i]);
}
}
ArrayList<Integer> list = new ArrayList<>(queue);
return list;
}
}

自己实现大顶堆写法:

import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<>();
if (input == null || k <= 0 || k > input.length) {
return list;
}
int[] kArray = Arrays.copyOfRange(input,0,k);
// 创建大根堆
buildHeap(kArray); for(int i = k; i < input.length; i++) {
if(input[i] < kArray[0]) {
kArray[0] = input[i];
maxHeap(kArray, 0);
}
} for (int i = kArray.length - 1; i >= 0; i--) {
list.add(kArray[i]);
} return list;
} public void buildHeap(int[] input) {
for (int i = input.length/2 - 1; i >= 0; i--) {
maxHeap(input,i);
}
} private void maxHeap(int[] array,int i) {
int left=2*i+1;
int right=left+1;
int largest=0; if(left < array.length && array[left] > array[i])
largest=left;
else
largest=i; if(right < array.length && array[right] > array[largest])
largest = right; if(largest != i) {
int temp = array[i];
array[i] = array[largest];
array[largest] = temp;
maxHeap(array, largest);
}
} }

2. 数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

思路

创建优先级队列维护大顶堆和小顶堆两个堆,并且小顶堆的值都大于大顶堆的值,2个堆个数的差值小于等于1,所以当插入个数为奇数时:大顶堆个数就比小顶堆多1,中位数就是大顶堆堆头;当插入个数为偶数时,使大顶堆个数跟小顶堆个数一样,中位数就是 2个堆堆头平均数。也可使用集合类的排序方法。

代码

import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution { PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
int count = 0;
public void Insert(Integer num) {
count++;
//当数据个数为奇数时,进入大根堆
if((count & 1) == 1){
minHeap.add(num);
maxHeap.add(minHeap.poll());
}else{
maxHeap.add(num);
minHeap.add(maxHeap.poll());
}
} public Double GetMedian() {
if(count == 0){
return null;
}
// 当数据个数是奇数时,中位数就是大根堆的顶点
if ((count & 1) == 1) {
return Double.valueOf(maxHeap.peek());
} else {
return Double.valueOf((minHeap.peek() + maxHeap.peek())) / 2;
}
} }

[算法]最小的K个数和数据流中的中位数的更多相关文章

  1. 代码题(3)— 最小的k个数、数组中的第K个最大元素、前K个高频元素

    1.题目:输入n个整数,找出其中最小的K个数. 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 快排思路(掌握): class Solution { public ...

  2. 编程算法 - 最小的k个数 红黑树 代码(C++)

    最小的k个数 红黑树 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出当中的最小k个数. 使用红黑树(multiset) ...

  3. 编程算法 - 最小的k个数 代码(C)

    最小的k个数 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出当中的最小k个数. 使用高速排序(Quick Sort)的方法 ...

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

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

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

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

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

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

  7. 算法练习:寻找最小的k个数

    参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...

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

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

  9. 算法笔记_035:寻找最小的k个数(Java)

    目录 1 问题描述 2 解决方案 2.1 全部排序法 2.2 部分排序法 2.3 用堆代替数组法 2.4线性选择算法   1 问题描述 有n个整数,请找出其中最小的k个数,要求时间复杂度尽可能低. 2 ...

随机推荐

  1. win10下快捷命令

    win10下可在win+r的输入框中: 1.gpedit.msc   //本地组策略编辑器 2.regedit    //注册表 3.secpol.msc   //本地安全策略 4.mstsc    ...

  2. php获取图片RGB颜色值的例子

    php获取图片RGB颜色值的例子 很多图片站点都会根据用户上传的图片检索出图片的主要颜色值,然后在通过颜色搜索相关的图片. 之前按照网上的方法将图片缩放(或者马赛克)然后遍历每个像素点,然后统计处RG ...

  3. 为你的网站加上SSL,可以使用HTTPS进行访问

    首先,我们使用的是nginx 将域名证书文件1_www.domain.com_bundle.crt .私钥文件2_www.domain.com.key保存到同一个目录,例如/usr/local/ngi ...

  4. webp技术探索

    不管是 PC 还是移动端,图片一直是流量大头,以苹果公司 Retina 产品为代表的高 PPI 屏对图片的质量提出了更高的要求,如何保证在图片的精细度不降低的前提下缩小图片体积,成为了一个有价值且值得 ...

  5. GGGGCCCC

    Evaluating and improving remembered sets in the HotSpot G1 garbage collector http://www.diva-portal. ...

  6. SQL分页参数传值 在存储过程中使用 动态SQL实现

    PROCEDURE [dbo].[SP_GetList] ( ), @arrearsStatus int, , --最小ID , --每页显示记录数 ) ) AS ); declare @strSQL ...

  7. 每日英语:Proactive Advice for Dealing With Grief: Seek Out New Experiences

    When her husband died of cancer 10 years ago, Becky Aikman says she experienced grief and adapted to ...

  8. Android 编程下 TextView 添加链接的一种方式

    通过如下这种方式给 TextView 添加的链接支持链接样式.点击事件.href 样式,代码如下: package cn.sunzn.tlink; import android.app.Activit ...

  9. Vue2键盘事件

    这两天学习了Vue.js 感觉组件这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记,学习一下Vue键盘事件 键盘事件 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...

  10. 多媒体文件格式之MKV

    [时间:2016-07] [状态:Open] MKV是一种开源的多媒体封装格式,是Matroska中应用比较多的格式之一.常见的后缀格式是.mkv(视频,包括音频和字幕)..mka(纯音频)..mks ...