面试题—— 找出一个无序整型数组中第k大的数。

题目简介:


经典面试题: 找出一个无序的整型数组中第k大的数。
函数接口如下:
int findKthLargestNum( int A[], int N,  int K)



解法一: 全排序 or 冒泡选择排序(K趟)

全排序: 
最简单的方法就是对整个数组排序(需要将整个数组装入内存),可以用快速排序和推排序。 (注意: 快排的平均时间复杂度为O(N log N),最坏为O(N^2); 堆排序的最坏和平均时间复杂度都是O(N* log N)。
总的时间复杂度为 O (N*log  N) + O(K) = O(N*log N)

部分排序:
当K很小时,我们一般希望能够进行部分排序,这就利用到了 冒泡排序和选择排序的特性。 我们可以进行K趟 冒泡排序或选择排序, 就可以找到第K大的数。
最坏时间复杂度O(N*K),空间复杂度O(1)

关于 O(N*logN)的算法和O(N*K)算法那个好,关键取决于K与log N的大小,一般K<<N.


解法二: 快排排序思想:

快速排序的需要多次的partition,每一次partition把数据分成两部分;大于key的数放在一边,小于key的放在另一边。
现在我们利用快排思想来解决这个问题, 我们每次partition将数据分为两部分,较小的数据Sl,  较大的数据Su,我们期望有一次partition可以得到正好Su.size() == K; 或者经过几次partition,正好找到几次较大的数据为K个。
对于每一次partition,我们根据较大数据部分Su进行如下操作:
注意:
若Su的元素个数==K,遍历这K个数最小的即为所求; 
若Su的元素的个数 <K, 在Sl中进行partition,找K-Su.length个。
若Su的元素的个数 > K, 对数组中的大数部分进行partition


代码实现:
对于数组A,大小为N,找到K个最大的数
快排是原地排序,我们每次对于给定数组中的范围[start,end]进行partition,返回pivot在A数组中对应的pos。若pos == K-1,表示我们找到了第k个最大的数。 若pos > or < K-1, 则在相应的区域继续进行partition,知道一个pivot返回对应pos == K-1。   

详细代码如下:
   
   
   
#include <iostream>
#include <cstdio> //包含语言重定向函数freopen的库
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
void printArray(int a[], int n){
for (int i=0; i<n; ++i){
cout<<a[i]<<" ";
}
cout<<endl;
}
/**
partition2 :
大集 | pivot | 小集
*/
int partition2(int A[], int start, int end){
//swap(A[start],A[rand()%(end -start)];
int pivot
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值