记录 1 道算法题
最小 k 个数
和第 k 小的数类似,可以用堆和排序进行解题。因为题目没要求按照升序或者降序返回,所以都差不多。
堆的话只要把堆内的数组返回就可以了,使用大顶堆。堆的实现可以看其他的文章
function smallestK(arr, k) {
const heap = new Heap((a, b) => b - a)
for (let i = 0; i < k; i++) {
heap.push(arr[i])
}
for (let i = k; i < arr.length; i++) {
const n = arr[i]
if (heap.data[0] > n) {
heap.pop()
heap.push(n)
}
}
return heap.data
}
排序的话有很多方法,这里使用快排。快排主要是找一个基准,然后分成左右两拨,进行递归处理。优化的方式是减枝,因为我们只需要排序 k 之前的数就可以了。
function smallestK (arr, k) {
fastSort(arr, 0, arr.length, k)
return arr.slice(0, k)
}
function fastSort(arr, start, end, k) {
if (start >= end) return
// 用随机的一个基准会比较好,这里固定使用第一个数
const p = arr[start]
let s = start + 1
for(let i = start + 1; i <= end) {
if (arr[i] < p) {
swap(arr, i, s)
s++
}
}
swap(arr, s - 1, start)
if (s > k) {
fastSort(arr, start, s - 1, k)
} else if (s === k) {
return
} else {
fastSort(arr, s, end, k)
}
}
function swap(arr, a, b) {
const t = arr[a]
arr[a] = arr[b]
arr[b] = t
}