码迷,mamicode.com
首页 > 其他好文 > 详细

剑指offer(29)最小的K个数

时间:2018-04-06 23:42:07      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:扫描   turn   思想   return   方法   number   第一个   比较   描述   

题目描述

输入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现在所在的下标返回
}

第二种:

略。

剑指offer(29)最小的K个数

标签:扫描   turn   思想   return   方法   number   第一个   比较   描述   

原文地址:https://www.cnblogs.com/wuguanglin/p/GetLeastNumbers_Solution.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!