无序数组中位数

这篇博客探讨了如何利用排序算法寻找数组的中位数,包括使用O(nlogn)时间复杂度的排序方法以及通过快速排序思想寻找第K大的数。对于奇数长度的数组,中位数是第(n+1)/2大的数,而偶数长度时,中位数是第n/2+1和第n/2大数的平均。此外,还介绍了利用最小堆在O(nlog(k))时间复杂度内求解中位数的方法,堆顶元素在奇数长度时即为中位数,偶数长度时需要结合堆顶下一个元素求平均值。
摘要由CSDN通过智能技术生成

1. 排序

对无序数组排序,然后可以直接得到该数组的中位数,时间复杂度为O(nlogn)。

2. 利用快排思想寻找第K大的数(时间复杂度为O(n))

先挑选一个数作为标准,以该元素为支点,将数组划分为两部分。

这个问题可以抽象化为寻找第K大的数,快排每排完一轮之后左侧都是比他小的元素,右侧都是比他大的元素,那么支点的index(假设为N-1)即为第N大的数。当N == K,我们就找到了第K大的数;当N > K时, 第K大的数在[0,N-1]范围内;当N < K时,第K大的数在[N+1,n-1] (n为数组长度)范围内,利用递归即可找到第K大的数。

具体到寻找中位数,可分为两种情况:如果数组长度为奇数,即为寻找第(n+1)/2大的数;如果为偶数,则为分别寻找第(n/2+1)和第(n/2)大的数,然后求其平均值。

3. 最小堆(时间复杂度为O(nlog(k)))

这个问题可以延伸至求数组的第K小的数。

  1. 取n/2+1个数建堆,将数组中剩余项与堆顶项进行比较,如果比堆顶项小,则直接丢弃;如果比堆顶项大,则入堆,然后重新调整堆的结构,更新堆顶元素,并推出堆中最小的数。
  2. 如果数组长度为奇数,堆顶项即为中位数;如果数组长度为偶数,则中位数为堆顶项以及推出第一个堆顶项之后的数平均。

在Java中,可以使用PriorityQueue来实现无序数组中位数。PriorityQueue是一个基于优先级堆的无界优先级队列,默认是一个最小堆。具体实现可以参考以下代码: ``` import java.util.PriorityQueue; public class Median { public static double median(int[] array) { int heapSize = array.length / 2 + 1; PriorityQueue<Integer> heap = new PriorityQueue<>(heapSize); for (int i = 0; i < heapSize; i++) { heap.add(array[i]); } for (int i = heapSize; i < array.length; i++) { if (heap.peek() < array[i]) { heap.poll(); heap.add(array[i]); } } if (array.length % 2 == 1) { return (double) heap.peek(); } else { return (double) (heap在Java中,可以使用PriorityQueue来实现无序数组中位数。PriorityQueue是一个基于优先级堆的无界优先级队列,默认是一个最小堆。具体实现可以参考以下代码: ``` import java.util.PriorityQueue; public class Median { public static double median(int[] array) { int heapSize = array.length / 2 + 1; PriorityQueue<Integer> heap = new PriorityQueue<>(heapSize); for (int i = 0; i < heapSize; i++) { heap.add(array[i]); } for (int i = heapSize; i < array.length; i++) { if (heap.peek() < array[i]) { heap.poll(); heap.add(array[i]); } } if (array.length % 2 == 1) { return (double) heap.peek(); } else { return (double) (heap.poll() + heap.peek()) / 2.0; } } public static void main(String[] args) { int[] array = new int[]{12, 34, 1, 209, 17, 900, -10}; System.out.println(median(array)); } } ``` 其中,首先定义了一个大小为数组长度一半加一的最小堆,然后将数组的前一半元素加入堆中。接着,遍历数组的后一半元素,如果当前元素比堆顶元素大,则将堆顶元素弹出,将当前元素加入堆中。最后,如果数组长度为奇数,则中位数就是堆顶元素;如果数组长度为偶数,则中位数就是堆顶元素和次顶元素的平均值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值