面试题30:最小的K个数
来源:互联网 发布:淘宝上找不到的衣服 编辑:程序博客网 时间:2024/05/22 02:26
题目:输入n个整数,找出其中最小的k个数。
1) On的时间复杂度,同样利用partition快排找到第k个数,然后比它小的都在左边,比他大的都在右边,输出K左边的数。
void GetLeastNumbers(int * numbers,int length,int k){if(numbers==NULL||length<=0||k>length||k<=0)return;int start=0;int end=length-1;int index=Partition(numbers,length,start,end);while(index!=k-1){if(index<k-1){start=index+1;index=Partition(numbers,length,start,end);}else{end=index-1;index=Partition(numbers,length,start,end);}}for(int i=0;i<k;i++){cout<<numbers[i]<<endl;}}
//快速排序中随机生成一个数字,将此大于此下标位置的数的元素放右边,小于的放左边int Partition(int * data,int length,int start,int end){if(data==NULL||length<=0||start<0||end>=length){throw new exception("invalid parameters");}//在起始位置和结束位置中随机生成一位数int index=randomInRange(start,end);//将index位置的数和最后一位交换,放置最后swap(&data[index],&data[end]);int small=start-1;//遍历数组for(index=start;index<end;index++){if(data[index]<data[end]){/*如果当前数小于分界元素,small++,和index相等,指向当前元素,向后遍历遇到大于分界元素的,small不变,直到遇到下一个小于分界元素的,对small再加1,此时small记录的就是第一个大于分界元素的元素下标,然后交换值*/small++;//如果small不指向当前位置if(index!=small){//交换当前元素和small位置的元素swap(&data[index],&data[small]);}}}++small;swap(&data[small],&data[end]);return small;//返回下标}//生成随机数int randomInRange(int start, int end) { srand(time(NULL)); return start + rand()%(end-start+1); }//交换两个数的值void swap(int * a,int * b){int temp=*a;*a=*b;*b=temp;}
1) O(nlogk)的时间复杂度,适合处理海量数据
我们可以先创建一个大小为K的数据容器来存储最小的K个数,接下来我们每次从输入的n个整数中读入一个数,如果容器中已有的数字少于K,则直接把这次读入的整数放入容器中;如果容器中已有K个数,就是容器满了,此时我们不能插入新的数字而只能替换已有的数字了。找出这K个数的最大值,然后拿这次待插入的整数和最大值相比较。如果待插入的值比当前已有的最大值小,则用这个数替换当前已有的最大值;如果待插入的值比当前已有的最大值还大,那么这个数不可能是最小的K个整数之一,于是我们可以抛弃这个数。我们可以用红黑树来实现这个数据容器,或者使用最大堆来实现,非常适合海量数据的处理。
typedef multiset<int, greater<int> > intSet;typedef multiset<int, greater<int> >::iterator setIterator;void GetLeastNumbers_Solution2(const vector<int>& data, intSet& leastNumbers, int k){ leastNumbers.clear(); if(k < 1 || data.size() < k) return; vector<int>::const_iterator iter = data.begin(); for(; iter != data.end(); ++ iter) { if((leastNumbers.size()) < k) leastNumbers.insert(*iter); else { setIterator iterGreatest = leastNumbers.begin(); if(*iter < *(leastNumbers.begin())) { leastNumbers.erase(iterGreatest); leastNumbers.insert(*iter); } } }}
java:
可以使用TreeSet,TreeSet中可以使元素按从小到大排序,遍历数组每次和最大的值比较。
public class TopK {public static void main(String[] args) {int[] array={0,5,2,7,9,11,12,4,3,6};PrintTopK(array,3);}public static void PrintTopK(int[] array,int k){if(array==null||k<1)return;TreeSet<Integer> ts=new TreeSet<Integer>();for(int i=0;i<array.length;i++){if(ts.size()<k){ts.add(array[i]);//如果容器中不够K个数,直接添加}else{if(array[i]<ts.last())//当前元素和ts最大值比(treeset中最后一个元素是最大值){ts.remove(ts.last());//移除treeset中的最大值ts.add(array[i]);//将当前元素插入}}}System.out.println(ts);}}
0 0
- 面试题30:最小的k个数
- 面试题30 最小的K个数
- 面试题30:最小的K个数
- 面试题30 最小的K个数
- 面试题30:最小的K个数
- 面试题30:最小的k个数
- 面试题30:最小的K个数
- 面试题30:最小的k个数
- 面试题30最小的k个数
- 面试题30:最小的k个数
- 面试题30:最小的k个数
- 面试题 30 : 最小的K个数
- 面试题26:最小的k个数
- 面试题:求最小的K个数。
- 面试题34:最小的K个数
- 面试题30.最小的K个数
- 剑指offer面试题30最小的k个数
- [剑指offer][面试题30]最小的k个数
- 中国计算机学会推荐国际学术期刊 (计算机图形学与多媒体)
- ASP.NET4.0课后习题答案
- Mac OS 下命令行编辑plist的方法
- s3c2440 ADC 应用程序编程
- iOS 内核堆利用技术点之 mach_msg ool
- 面试题30:最小的K个数
- 从多层感知器到卷积网络(一)
- 2.感知器学习算法(待修)
- poj3026(bfs+prime)
- recursion demo(problem from Stanford cs106b course reader)
- uva 12470(矩阵快速幂)
- Java中的运行期类型鉴定
- AE加载地图时报错:The operation was attempted on an empty geometry.
- uva live 3882 And Then There Was One 约瑟夫环