[路飞]_剑指 Offer 40. 最小的k个数

158 阅读1分钟

题目地址
B站地址

题目描述

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1:

输入: arr = [3,2,1], k = 2
输出: [1,2] 或者 [2,1]

示例 2:

输入: arr = [0,1,2,1], k = 1
输出: [0]

解题思路1

  • 申明一个result作为返回数组
  • 循环当前数组,判断如果k为0,就直接返回一个空数组
  • 如果result的数组长度小于k,那么直接push当前arr[i],并且对数组进行排序,最大的放在第一位
  • 如果result[0]大于arr[i]的话,那么就把result[0]删除,并且把arr[i]push进入,且对result进行排序。
  • 最后返回result

代码

var getLeaseNumbers = function(arr, k){
    let result = [];
    for(let i = 0; i < arr.length; i++){
        if(k === 0) return [];
        // result的长度小于k,就直接添加
        if(result.length < k){
            result.push(arr[i]);
        } else if(result[0] > arr[i]){ // result数组的第一个元素大于arr[i]的话,需要把result中的第一个给删掉,并且把arr[i]给添加进去
            result.shift();
            result.push(arr[i]);
        }
        // 每次遍历完都需要对result从新排序
        result.sort((a,b) =>{b - a})
    }
    return result;
}

解题思路2

var getLeaseNumbers = function(arr, k){
    // 维护一个小顶堆
    let list = [];
    for(a of arr){ // 循环数组
        let flag = false; // 申明一个标识位
        for(let j = 0; j <list.length; j++){
            // 判断list里面的值是否大于a
            if(list[j] > a){
                // 将a插入到j的前面
                list.splice(j, 0, a);
                flag = true;
            }
        }
        if(!flag){ // 第一次进来走这里,把第一个值push进去
            list.push(a);
        }
        // 把length大于k的数据删掉
        if(list.length > k) list.pop();
    }
    return list;
}