Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
输入整数数组 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]
二、思路分析
- 最小的k个数,可以初始建立一个k长度的大根堆,堆内一直维持k个元素,如果堆顶元素大于堆外元素,将堆外元素与堆顶元素互换,再堆化,时间复杂度为O(nlogk)。
- 函数包括一个建立大根堆的函数,和堆化的函数。
- 建立大根堆函数,从最后一个父节点开始,不断堆化。
三、AC 代码
func getLeastNumbers(arr []int, k int) (ans []int) {
//建立k大小的堆
heap := make([]int,k)
for i := 0;i<k;i++ {
heap[i] = arr[i]
}
if k == 0 {
return ans
}
buildMaxHeap(heap,k)
for i := k ;i < len(arr);i++ {
if heap[0] > arr[i] {
arr[i],heap[0] = heap[0],arr[i]
maxHeapify(heap,0,k)
}
}
return heap
}
//建立大根堆
func buildMaxHeap(arr []int,heapsize int) {
for i := heapsize/2; i>=0 ;i-- {
maxHeapify(arr,i,heapsize)
}
}
//堆化
func maxHeapify(arr []int,i,heapsize int) {
l,r := i*2+1,i*2+2
largest := i
if l < heapsize && arr[l] > arr[largest] {
largest = l
}
if r < heapsize && arr[r] > arr[largest] {
largest = r
}
if largest != i {
arr[largest],arr[i] = arr[i],arr[largest]
maxHeapify(arr,largest,heapsize)
}
}
四、总结
如果要找出前k个小元素,建立大根堆,这样堆可以维持k的大小。如果建立小根堆,则需要将所有元素放入堆内,时间消耗更多。