描述
给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组
示例1
输入:
[4,5,1,6,2,7,3,8],4
返回值:
[1,2,3,4]
1)方法一:使用数组的sort方法
function GetLeastNumbers_Solution(input, k)
{
if(k>input.length){
return [];
}else{
return input.sort(function(a,b){
if(a>b){
return 1;
}else if(a<b){
return -1;
}else{
return 0;
}
}).slice(0,k)
}
}
module.exports = {
GetLeastNumbers_Solution : GetLeastNumbers_Solution
};
2)方法二:冒泡排序,排k趟
function GetLeastNumbers_Solution(input, k)
{
//冒泡排序,执行k次即可
let res = [];
// K>数组的长度,返回一个空的数组
if(input.length < k){
return res;
}
// 执行k趟冒泡排序,每次把最小的数字冒泡到最后位置
for(let i=1; i<=k; i++){
let flag = true; //记录当前这趟是否发生交换
if(true){
flag = false; //未交换
for(let j=0; j<input.length-i; j++){
if(input[j]<input[j+1]){
let temp = input[j];
input[j] = input[j+1];
input[j+1] = temp;
flag = true; //交换
}
}
}//if
}
// 将排序的k个元素存入res
for(let i = input.length-1; i >= input.length-k; i--){
res.push(input[i]);
}
return res;
}
module.exports = {
GetLeastNumbers_Solution : GetLeastNumbers_Solution
};
补充:
stringObject.slice(start,end)
返回值:一个新的字符串。包括字符串 stringObject 从 start 开始(包括 start)到 end 结束(不包括 end)为止的所有字符。
3)堆排序
- 创建k个元素的大根堆;
- 将 剩余的元素与大根堆的堆顶进行比较:如果比堆顶小,则和堆顶交换,并调整;
- 最后得到的大根堆,即为最小的k个数字
function GetLeastNumbers_Solution(input, k)
{
//堆排序。建立含有k个元素的大根堆
let h = input.slice(0,k);
build(h,k);
for(let i=k;i<input.length;i++){
if(input[i]<h[0]){
h[0] = input[i];
adjust(h,k,0)
}
}
return h;
}
function build(h,k){
if(k==1){
return;
}
for(let i=Math.floor(k/2)-1;i>=0;i--){
adjust(h,k,i);
}
}
function adjust(h,k,i){ //调整为大根堆
while(true){
let max = i;
if((i*2+1)<k && h[i*2+1]>h[max]){
max = i*2+1
}
if((i*2+2)<k && h[i*2+2]>h[max]){
max = i*2+2
}
if(max==i){
return;
}else{
let temp = h[i];
h[i] = h[max];
h[max] = temp;
i = max;
}
}
}
module.exports = {
GetLeastNumbers_Solution : GetLeastNumbers_Solution
};