「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」
看一百遍美女,美女也不一定是你的。但你刷一百遍算法,知识就是你的了~~
谁能九层台,不用累土起!
题目
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
提示:
0 <= len(arr) <= 1000000 <= k <= min(100000, len(arr))
解题思路
-
常规操作,暴力解yyds
-
我们使用
sort排序,然后截取0-k的数返回
解题代码
var smallestK = function(arr, k) {
return arr.sort((a,b)=>a-b).splice(0,k)
};
使用大顶堆
先回顾一下大顶堆的概念
大顶堆:每个结点的值都大于或等于其左右子结点的值。
如果是排序,求升序用大顶堆,求降序用小顶堆。
本题要求的是最小的k个,符合大顶堆。
我们来维护一个大小为k的大顶堆。
-
如果
k为0,我们直接返回空数组 -
遍历
arr数组,如果当前顶堆不满k个时,将遍历到的元素塞入队列 -
否则,就判断当前元素是否小于堆顶的元素
-
如果小于堆顶的元素,我们将堆顶的元素出队,将这个元素入队
var smallestK = function(arr, k) {
if(!k) return [] // 排除 k===0 的情况 我们直接返回空数组
const maxQueue = new MaxPriorityQueue()
arr.forEach(v=>{ //遍历arr数组
if(maxQueue.size()<k){ // 如果当前顶堆不满k个时,将遍历到的元素塞入队列
maxQueue.enqueue(v)
}else if(maxQueue.front().priority>v){ // 将堆顶的元素与遍历到的值进行比较,判断当前元素是否小于堆顶的元素
maxQueue.dequeue() // 堆顶的元素出堆
maxQueue.enqueue(v) // 当前元素入队
}
})
return maxQueue.toArray().map(v=>v.element)
// 需要注意的是,大顶堆转为数组后的格式是形如
// [ { priority: 1, element: 1 } ] 而其中的 element才是实际的值 我们需要利用map取出
};
如有任何问题或建议,欢迎留言讨论!