题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
题目分析
这题有两种方法来做。
第一种就是基于partition的方法,详见我的另一篇文章:基于快排思想查找第K大的数或第K小的数。
第二种就是利用一个长度为k的额外容器,来存储最小的K个数字。容器未满则填满,再添加数字是,将数字和容器的最大值比较,小的话就替换,大的话舍去。
这个容器要求可以直接得到最大值、能删除最大值,能添加值。那么很容易想到应该用最大堆当这个容器,当然也可以用红黑树来实现。由于事先容器比较复杂,这里就不给出代码了。
代码
第一种:
function GetLeastNumbers_Solution(input, k) { if(input.length==0||k>input.length||k<1) return []; let left=0,right=input.length-1; let key=partition(input,left,right); while(key!=k-1){ if(key>k-1){ key=partition(input,left,key-1); }else{ key=partition(input,key+1,right); } } let res=input.slice(0,key+1); res.sort((a,b)=>a-b); return res; } function partition(a,left,right){ let key=a[left];//一开始让key为第一个数 while(left<right){//扫描一遍 while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较 right--; } [a[left],a[right]]=[a[right],a[left]];//交换 while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较 left++; } [a[left],a[right]]=[a[right],a[left]];//交换 } return left;//把key现在所在的下标返回 }
第二种:
略。