Algorithm学习笔记 --- 寻找 K 大数

来源:互联网 发布:移动硬盘mac无法拷贝 编辑:程序博客网 时间:2024/05/17 01:57

Q:

给你一个无序的序列,要你找出第K大的数是什么?


Answer:


Answer 1:

利用Hash,桶排序等方式,是第一个想到的(编程珠玑中所记)

假设数列中最大数为max,最小数为min,那么首先做一个数组长度为max – min + 1,

然后做散列函数为an – min,对于冲突的处理是计数,最后从后往前扫描一次整个新建的数组,

即可得到第k大的数。这样看似可以在O(n)的复杂度内解决问题,是一个经典的空间换时间的办法,

但是具体情况是,其实这个算法的时间复杂度是 O( n * ( max – min ) )的,所以这个的时间复杂度

全取决于数组的最大与最小数的差。但是一般在实际的数据中,数列是很分散的,如果特别分散的话,

完全有可能max – min 是远大于n的,那么这个效果就非常差了,


代码如下:O( n * ( max – min ) )

//Find K-th Number#include <iostream>#include <stdio.h>using namespace std;int find_k(int p[], int n, int k){int KList[k];for(int i = 0; i < k; i++)kList[i] = 0;for(int i = 0; i < n; i++){for(int j = 0; j < k; j++){if(p[i] > kList[j]){for(int I = K - 1; I > j; I--){kList[I] = kList[I - 1]kList[j] = p[i]break;}}}}return kList[k - 1]}int main(){//....//return 0}




Answer2:


    编程之美的解法:使用部分快排的方法

方法是从最开始的原始方法开始讨论展开的。得到k个最大数,首先做排序,然后取前k个即可,

而用快排或者堆排序,这样的时间复杂度是o(N*logN),于是基于这样的时间复杂度为起点,开始逐步的优化。

优化的原因是,要得到k个最大数,只需要前k个数有序,时间复杂度的优化,只能从去除对k个以后的数进行排序展开。

优化方法如下:首先随机在数列中找到一个数,作为轴值,将数列划分成Sa和Sb两个部分,其中Sa中存放大于或等于轴值的数,Sb存放小于轴值

的数,划分完成后,有如下两种情况:



1.Sa元素小于等于k,那么k个最大数为Sa中所有数,以及Sb中最大的k-|Sa|个数

2.Sa元素大于等于k,那么需要找到Sa中最大的k个数


代码如下:o(N*logN)

int find_k(vector find, int k){if(find.size() < k){return 0;}int p = find.at(0);vector findA, findB;for(int i = 1; i < find.size(); i++){if(find.at(i) >= p)findA.push_back(find.at(i))elsefindB.push_back(find.at(i))}if(findA.size() == (k - 1)){return p;}else if(findA.size(0 > (k - 1)){return find_k(findA, k);}else{return find_k(findB, k findA.size());}}


Answer3:用 小顶堆优化

其实这是没有意义的事情,毕竟我要的只是第k个数,所以我只要知道我那k个数组中,

最小的那个数即可,也就是一直保存的k个数,可以是无序的,但是,一定要知道其中最小值,

有一个最小值,并且整体不一定有序,这样的数据结构一下就想到了最小值堆,首先将堆的接口声明如下


代码如下:

O(N * logK)


classminHeap{ private: int*Heap;//用于存放堆元素的数组 intsize;//数组大小 intn;//堆中元素个数 voidshiftdown(int);//堆的下拉操作 public: minHeap(int*Heap,intnum,intmax) boolisLeaf(intpos)const intleftchild(intpos)const intrightchild(intpos)const intparent(intpos)const boolinsert(constint); boolremoveMin(int&); intgetMin(); }; 



0 0
原创粉丝点击