博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
找出无序数组中位数的方法
阅读量:3904 次
发布时间:2019-05-23

本文共 2238 字,大约阅读时间需要 7 分钟。

今早上在LintCode上做到了这种类型的题目,题目要求找到无序数组中位数在数组的位置,一开始想到的是利用快排的思想来做,但是由于只有十五分钟的时间,就直接用最普通的方式做了,思路是map记录位置+sort排序,水过去了。

找无序数组中位数我想着我之前逛知乎的时候遇到过,用最大堆和最小堆来做的。想了想,遇到这么多次,那就整理下方法吧。

这里中位数的定义是数组元素个数/2

1 直接排序找中位数

直接利用自带的sort方法排序,然后返回数组的中间索引的值

代码如下:

//1.直接排序    public static int findMediaMethod1(int[] a)    {
if(a.length==0) return -1; Arrays.sort(a); return a[(a.length-1)/2]; }

第一种方法太暴力了,我们只需要中位数即可,而不需要对数组中所有的元素进行处理。

这就引申出了第二种方法:

2 利用快排思想

快排的基本思想是选取一个哨兵元素,然后设立两个指针left,right,分别指向左端和右端,两个指针相向运动,当左右指针都遇到了违反数组次序的元素的时候左右指针交换元素(违反数组次序是指左指针找到了大于哨兵元素的元素或右指针找到了小于哨兵元素的值),这样当左右指针相遇的时候,左边的数组元素一定小于等于哨兵元素,右边的数组元素一定大于等于哨兵元素。我们可以利用这一性质来找中位数,每次进行快排操作后记录下哨兵元素的位置,如果大于中间元素的话,则我们只需要对左边进行快排操作,当小于中间元素,我们只需要对右边进行快排操作,跟二分查找很像。

代码如下:

//2.利用快排原理进行排序    public static int findMediaMethod2(int[] a)    {
if(a.length==0) return -1; //中位数位置 int mid=(a.length-1)/2; //左右指针位置 int left=0,right=a.length-1; //进行快排操作后哨兵元素的位置 int qsIdx=0; qsIdx = quickSort(left,right,a); while(true) {
//System.out.println("qsIdx= "+qsIdx); if(qsIdx==mid) {
break; } else if(qsIdx
=target) right--; a[left]=a[right]; while(left
<=target) left++; a[right]=a[left]; } //System.out.println("left="+left); a[left]=target; return left; }

3 利用大小堆性质

第三种方法我是看的牛客网上的一个回答才会的。这里附上链接:

大顶堆存数组中较小部分的元素,小顶堆存数组中较大部分的元素,相当于将数组分成两半了,这样
大顶堆的堆顶或小顶堆的堆顶就是我们找的中位数。
如何实现呢?
1. 当插入堆中的元素个数为偶数时,将当前元素插入大顶堆,将大顶堆的堆顶元素插入小顶堆
2. 当插入堆中的元素个数为奇数时,将当前元素插入小顶堆,将小顶堆的堆顶元素插入大顶堆
hhh,是不是很神奇。
代码如下:

//3.利用大顶堆和小顶堆性质进行排序    public static int findMediaMethod3(int[] a)    {
if(a.length==0) return -1; Queue
minHeap = new PriorityQueue
(); Queue
maxHeap = new PriorityQueue
(new Comparator
() {
@Override public int compare(Integer o1, Integer o2) {
return o2-o1; } }); for (int i=0;i

总结

上面的三种方法,第一种肯定是不提倡的,第三种的话,因为一次操作就需要一次堆插入操作(log(m))(m表示堆中元素数目),n次操作的话就是nlog(m) ,第二种感觉的话应该是nlog(n)? 不过最官方的肯定是第三种方法。

转载地址:http://dcaen.baihongyu.com/

你可能感兴趣的文章
百练OJ-2815 城堡问题【DFS】
查看>>
CODE[VS] 1025 选菜 【背包】
查看>>
POJ 1724 ROADS【DFS+剪枝】
查看>>
AOJ 847 整数拆段
查看>>
AOJ 848 分数拆分
查看>>
UVA 133 The Dole Queue 【约瑟夫环】
查看>>
XDOJ 1208 B.笑爷买房 【DFS】
查看>>
部门年度工作总结的内容
查看>>
pandas学习笔记
查看>>
Numpy笔记
查看>>
正则表达式
查看>>
python线程进程笔记
查看>>
TensorFlow初学者必须了解的55个经典案例
查看>>
机器学习笔记
查看>>
数十种TensorFlow实现案例汇集:代码+笔记
查看>>
python记录的错误与知识
查看>>
内核中各种套接字的关系
查看>>
linux sysctl 参数实现 暨 ip_forward参数对Linux内核转发影响分析
查看>>
linux 路由表 的一些相关资料
查看>>
Linux 路由 学习笔记 之三 路由查找流程分析
查看>>