题目描述

输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

运用知识点,最大堆与最小堆

【剑指offer】最小的k个数_最小堆
【剑指offer】最小的k个数_最小堆_02
思路:
(1)最大堆保证了,根节点的值大于左右孩子,因此在上述最大堆中(第一张图),始终确保最顶端的根节点最大,比如10 ,比下面节点的值都大。这样就能保证堆中可以存放列表中最小的k个数,而最小堆就可以存放堆中最大的k个数
(2)当有一个数,如7 ,插入到最大堆中,先与10进行比较,因7<10,所以7与10进行替换,同时比较左右孩子节点,6与8 ,因6<8,所以7与8(左右孩子节点中的较大者)进行替换,因为如果7与6进行替换,则6还要与8进行替换,增加了替换顺序
(3)依次类推,调整堆的过程,所以解决此问题,分两步走,第一步建立最大堆,第二步调整最大堆。

实现代码

# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
MaxHeap=[]
def createMaxHeap(num):
MaxHeap.append(num)
currentIndex = len(MaxHeap)-1
while currentIndex!=0:
parentIndex=(currentIndex-1)//2
if MaxHeap[parentIndex] < MaxHeap[currentIndex]:
MaxHeap[parentIndex],MaxHeap[currentIndex] = MaxHeap[currentIndex],MaxHeap[parentIndex]
else:
break

def adjustMaxHeap(num):
if num < MaxHeap[0]:
MaxHeap[0] = num
index = 0
maxlen=len(MaxHeap)
while index < maxlen:
leftchild_index = 2*index+1
rightchild_index = 2*index+2
largerindex=0

if rightchild_index < maxlen:
if MaxHeap[leftchild_index] < MaxHeap[rightchild_index]:
largerindex=rightchild_index
else:
largerindex=leftchild_index
elif leftchild_index < maxlen:
largerindex=leftchild_index
else:
break
if MaxHeap[index] < MaxHeap[largerindex]:
MaxHeap[index],MaxHeap[largerindex]=MaxHeap[largerindex],MaxHeap[index]
index=largerindex

inputlen=len(tinput)
if k<=0 or inputlen<k:
return []

for i in range(inputlen):
if i < k :
createMaxHeap(tinput[i])
else:
adjustMaxHeap(tinput[i])
MaxHeap.sort()
return MaxHeap