寻找无序数组中的第K大数和前K大数
来源:互联网 发布:牛头701在淘宝上叫什么 编辑:程序博客网 时间:2024/05/16 17:08
两个问题互相可以转化。如果可以找到第K大数,那么只再需要O(N)就可以找齐剩余的前K大数。如果可以找到前K大数,那么只再需要O(K)就可以找到第K大数。
先排序,在找第K个。O(NlgN)
快速排序的思想,可以做到平均效率O(N)
随机选一个元素,把所有小于等于这个元素的数移到左边,所有大于这个元素的数移动到右边。如果这个元素成了第K个数,直接返回这个数。
如果左边的个数大于K,不管右边的数了,在左边重复上面的过程。
如果左边的个数等于T<K,不管左边的数了,重复上面的过程,只是K=K-T-1。
平均情况下,第一次划分的时间复杂度是O(N),第二次是O(N/2),总共是O(N+N/2+N/4+...)=O(N)
#include "stdio.h"#include "stdlib.h"using namespace std;const int INCORRECT=-1;int FindKth(int d[], int left, int right, int k){if(left>right)return INCORRECT;else if(left==right&&k!=1) return INCORRECT;else if(left==right&&k==1) return d[left];else if(k>right-left+1) return INCORRECT;int num=d[left];int start=left,end=right;while(start<end){while(start<end&&d[end]>num) end--;d[start]=d[end];while(start<end&&d[start]<=num) start++;d[end]=d[start];}d[start]=num;int move = start-left + 1;if(move==k)return d[start];else if(move<k)return FindKth(d,start+1,right,k-move);elsereturn FindKth(d,left,start-1,k);}int main(){int data[10]={1,31,4,52,6,4,77,41,62,94};printf("%d\n",FindKth(data,0,9,9));}所以上对于两个问题,理论复杂度都可以做到O(N)。
不过实际上,可能存在数组非常巨大,读取的次数越少越好。如果K比较小,可以用priority queue来存储前K的数。这样只需要读取一遍数组就可以,复杂度是O(N+N*lgK)。
如果N非常巨大,且K=N/2,该如何处理?不知道。
- 寻找无序数组中的第K大数和前K大数
- 寻找无序数组中的第K大数
- 寻找无序数组中的第K大数
- 寻找无序数组中的第K大数
- 寻找数组第二大数和第K大数
- 寻找前K大数
- 寻找第k大数
- 寻找数组中第K大数
- 整数无序数组求第K大数(暴力|快排)
- 第(前)k大数问题
- 第(前)k大数问题
- 寻找数组中第K大数---使用堆
- 【算法】寻找数组第K大数算法总结
- 寻找前K大数(复习各种排序)
- 寻找第K大数的方法
- 寻找第K大数方法总结
- 寻找第k大数(快排思想)
- POJ3579 Median 寻找第K大数
- 《Head First设计模式》要点(六)
- JRE(version: 1.6.0_26-b03)的JVM自动挂掉
- 如何防止DNS被修改
- 排序小结
- 吃饭,睡觉,打豆豆任务二
- 寻找无序数组中的第K大数和前K大数
- C语言可执行程序如何通过运行直接调用
- 云计算时代的运维职位展望
- 无线局域网DDoS攻击概述
- InfoPath works with SharePoint list
- 信息王国“削藩”之战
- HP郭立航:磁带库守住最后一道防线
- 航天八院借助第九维度实现全员预算
- 2012年五个最严重的移动威胁