Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目分析
输入整数数组 arr
,找出其中最小的 k
个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
思路讲解
我们可以维护⼀个⼩根堆⽤来给所有元素排序。排序后堆中的前K个元素就是我们需要的元素
示例
示例1:
输入: arr = [3,2,1], k = 2
输出: [1,2] 或者 [2,1]
示例2:
输入: arr = [0,1,2,1], k = 1
输出: [0]
代码
/**
* @param {number[]} arr:数组arr
* @param {number} k:找出其中最小的k个数
* @return {number[]}
*/
var getLeastNumbers = function(arr, k) {
let len = arr.length // 获取数组的长度
let res = [] // 定义res,存储要返回的数组
// 处理边界条件
if (k === 0) return [] // k等于0,直接返回
if (k === len) return arr // k等于数组长度,直接返回,要返回所有的数组
// 把所有的数全放到小根堆中,每一次出堆,出堆的结果就是我们想要的,拿出来之后,就放到数组中
buildHeap(arr)
for (let i = 1; i <= k; i++) {
res.push(arr[0])
swap(arr, 0, len - i)
heapAdjust(arr, 0, len - i)
}
return res
};
var buildHeap = function (arr) {
let len = arr.length
for (let i = Math.floor(len / 2); i >= 0; i--) {
heapAdjust(arr, i, len)
}
}
var swap = function (arr, i, child) {
if (i === child) return
arr[i] = arr[child] + arr[i]
arr[child] = arr[i] - arr[child]
arr[i] = arr[i] - arr[child]
}
var heapAdjust = function (arr, i, len) {
let child = i * 2 + 1
while (child < len) {
if (child + 1 < len && arr[child] > arr[child + 1]) {
child = child + 1
}
if (arr[child] < arr[i]) {
swap(arr, i, child)
i = child
child = i * 2 + 1
} else {
break
}
}
}