面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度,

但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况下是O(n+klogn),最坏的情况是O(nlogn)

把两种方法整理一下,我还是推荐使用小顶堆的方法,因为它不仅可以求第K大,还可以求前K大。。。

一。快排。借用了快排的partition思想,其实是一种分治的方法。对于一个partition,他左边的数小于他,右边的数全大于他

那么:

  1.如果他本身就是第K个数,直接返回。

  2.如果他的下标是比K大的某个数,那么第K小数肯定出现在他左边。那么到partition的左边递归地求解

  3.如果他的下标是比K小的某个数,那么第K小数肯定出现在他右边。那么到partition的右边递归地求解

唯一需要注意的地方是,要注意在递归的过程中,第K小数是一个相对值,即相对于区间[l,r]的左边界l;

#include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int a[maxn];
int n = ,k = ; int part(int low, int high)
{
int pivot = a[low];
while(low < high){
while(low < high&&a[high] >= pivot) high--;
a[low] = a[high];
while(low < high&&a[low] <= pivot) low++;
a[high] = a[low];
}
a[low]=pivot;
return low;
} int quicksort(int l, int r, int k){
int pos = part(l,r);
if(pos - l + == k) return a[pos];
else if(pos - l + > k) return quicksort(l,pos-,k);
else return quicksort(pos+,r,k-(pos-l+));
} int main()
{
srand((unsigned)time(NULL));
for(int i = ; i < n; ++i){
a[i] = rand()%(n<<);
}
for(int i = ; i < n; ++i)
printf("%d ",a[i]);
printf("\n");
int x = quicksort(,n-,k);
printf("%d\n", x);
}

二。小顶堆

使用堆可以求出最小的元素,通过不断地弹出元素,就可以找到第K大的元素

#include <bits/stdc++.h>
using namespace std;
const int maxn = ;
int a[maxn];
int n,k; void adjust_heap(int rt,int n)
{
int x=a[rt],pos = rt;
while(rt <= n){
int lc = rt << ,rc = lc|;
if(lc <= n&&a[lc] < x) pos = lc;
if(rc <= n&&a[rc] < a[pos]) pos = rc;
if(pos == rt) break;
a[rt] = a[pos];
rt = pos;
}
a[pos] = x;
} int search_k()
{
for(int i = n/;i >= ; --i){//建堆的复杂度是O(n)的
adjust_heap(i,n);
}
int sz = n;
for(int i = ; i < k; ++i){//每次弹出要向下调整,调整K次,复杂度为O(Klogn)
a[] = a[sz--];
adjust_heap(,sz);
}
return a[];
}
int main()
{
srand((unsigned)time(NULL));
scanf("%d%d",&n,&k);
for(int i = ; i <= n; ++i){
a[i] = rand()%(n<<);
}
for(int i = ; i <= n; ++i)
printf("%d ",a[i]);
printf("\n");
int x = search_k();
printf("%d\n", x);
}

求一个数组中第K小的数的更多相关文章

  1. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  2. 选择问题(选择数组中第K小的数)

    由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小 ...

  3. 每天一道算法题(32)——输出数组中第k小的数

    1.题目 快速输出第K小的数 2.思路 使用快速排序的思想,递归求解.若键值位置i与k相等,返回.若大于k,则在[start,i-1]中寻找第k大的数.若小于k.则在[i+1,end]中寻找第k+st ...

  4. 【medium】4. Median of Two Sorted Arrays 两个有序数组中第k小的数

    There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  5. 找轮转后的有序数组中第K小的数

    我们可以通过二分查找法,在log(n)的时间内找到最小数的在数组中的位置,然后通过偏移来快速定位任意第K个数. 此处假设数组中没有相同的数,原排列顺序是递增排列. 在轮转后的有序数组中查找最小数的算法 ...

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

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

  7. 求一个数组的最大k个数(java)

    问题描写叙述:求一个数组的最大k个数.如,{1,5,8,9,11,2,3}的最大三个数应该是,8,9,11 问题分析: 1.解法一:最直观的做法是将数组从大到小排序,然后选出当中最大的K个数.可是这种 ...

  8. 数组中第K小的数字(Google面试题)

    http://ac.jobdu.com/problem.php?pid=1534 题目1534:数组中第K小的数字 时间限制:2 秒 内存限制:128 兆 特殊判题:否 提交:1120 解决:208 ...

  9. 笔试题&amp;面试题:找出一个数组中第m小的值并输出

    题目:找出一个数组中第m小的值并输出. 代码: #include <stdio.h> int findm_min(int a[], int n, int m) //n代表数组长度,m代表找 ...

随机推荐

  1. Linux查看代码量

    利用find  xargs  wc可方便的计算出某个目录下源文件的代码量find sourcecode_dir_path -type f -name "*.c" -print0 | ...

  2. (转) [教程] Unity3D中角色的动画脚本的编写(一)

    ps: 这两天研究unity3d,对动画处理特别迷糊,不知FBX导入以后,接下来应该怎么操作,看到这篇文章,感觉非常好,讲解的很详细. 已有好些天没写什么了,今天想起来该写点东西了.这次我所介绍的内容 ...

  3. C#获取文件夹下指定格式的所有文件

    C#获取文件夹下指定格式的所有文件的方法,虽然很简单,但还是分享一下吧,用到时可以稍加修改和优化就可以使用. 获取指定目录下所有文件 //最要使用 System.IO.Directory.GetFil ...

  4. 应用框架 ViewPager Tab Fragment SlidingMenu

    介绍 常见的应用框架 框架一:多个tab+Fragment,点击不同的tab加载不同的Fragment,不能滑动切换只能点击切换: 框架二:多个tab+ViewPager+FragmentPagerA ...

  5. NPOI控件的使用导出excel文件和word文件

    public HttpResponseMessage GetReportRateOutput(DateTime? begin_time = null, DateTime? end_time = nul ...

  6. requirejs和r.js的心得

    requirejs的GitHub:requirejs r.js的GitHub:r.js grunt-contrib-requirejs的GitHub:grunt-contrib-requirejs r ...

  7. maven第5章坐标和依赖

    5.5依赖范围 runtime:运行时依赖范围 举的例子是JDBC驱动实现,不理解? 编译的时候只需要引入jdk提供的jdbc类和方法,比如java.sql.*;这时编译没有报错,但是没有引入mysq ...

  8. 用CSS边框图像让你的网站更漂亮

    不久之前,添加一些装饰性元素,例如给网页中的图片添加花哨的边,以及耐心调整CSS文件才能使你的网页看起来不错.然而现在CSS已经做出了改变,用复杂的边框装饰你的网站只需几行代码.这篇文章将告诉你如何做 ...

  9. java中保留几位小数

    public class NumUtils { /** * 保留两位小数 * * @param d * @return */ public static String get2Wei(double d ...

  10. Android Fragment用法之给Activity创建事件回调

    在某些案例中,可能需要Fragment与Activity共享事件.在Fragment内部定义一个回调接口是一个好方法,并且规定由持有它的Activity实现这个回调方法.当Activity通过接口接受 ...