[路飞]_程序员必刷力扣题: 剑指 Offer 40. 最小的k个数

139 阅读1分钟

剑指 Offer 40. 最小的k个数

输入整数数组 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]

限制:

  • 0 <= k <= arr.length <= 10000
  • 0 <= arr[i] <= 10000

排序截取搞定

思路 要求最小的k个数

我们直接用js的sort排序方法对数字进行正序排序,从小到大排序

然后再截取前k个元素即可

var getLeastNumbers = function(arr, k) {
    if(!arr.length) return []
    arr.sort((a,b)=>a-b)
    return arr.splice(0,k)
};

堆排序

思路 这里我们可以使用小顶堆来处理

要找到最小的k个数

我们在用小顶堆的时候,每次循环会找到一个最小的元素,只需要执行k次就能找到k个最小的数字了

我们这里把找到的元素放在数组末尾,最后只需要截取末尾k个元素就好了

两个边界条件可以直接处理:

  • k===0:直接返回空
  • k===arr。length :直接返回arr
var len;  
 
function buildMaxHeap(arr) {   // 建立小顶堆
    len = arr.length;
    for (var i = Math.floor(len/2); i >= 0; i--) {
        heapify(arr, i);
    }
}
 
function heapify(arr, i) {     // 堆调整
    var left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i;
 
    if (left < len && arr[left] < arr[largest]) {
        largest = left;
    }
 
    if (right < len && arr[right] < arr[largest]) {
        largest = right;
    }
 
    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest);
    }
}
 
function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
 
function heapSort(arr,k) {
    buildMaxHeap(arr);
    
    for (var i = arr.length - 1; i > 0; i--) {
        if(arr.length-len===k) break;
        swap(arr, 0, i);
        len--;
        heapify(arr, 0);
    }
    return arr.slice(len);
}
var getLeastNumbers = function(arr, k) {
    if(k===arr.length) return arr
    return heapSort(arr,k)
};