剑指offer:获取最小的k个数

 

思路1:

用一个长度为k的list存放k个最小数字,遍历数组,每来一个数,将这个数和list中的最大数比较,如果比最大数小,那就把最大数换出来。

这个思路是对的,不过可以接着优化。不用list,而是用一个大根堆。

大根堆的定义:

        一棵满二叉树;根 > left , right  

数组中大根堆的存放方式:

         index 为 i 的节点的root 的index为 (i-1)//2;它的左右子节点的index为 2*i+1 ,2*i+2

自己构建大根堆/小根堆:

# -*- coding:utf-8 -*-
import heapq
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        if k>len(tinput) or k==0:
            return []
        
        # 用前 k 个数构建大根堆
        maxh = []
        for num in tinput[:k]:
            heapq.heappush(maxh,-num)
        
        # 依次把数插入大根堆
        for num in tinput[k:]:
            if num < -maxh[0]:
                heapq.heapreplace(maxh,-num)
        for i in range(len(maxh)):
            maxh[i] = -maxh[i]
        maxh.sort()
        return maxh
    
    def swap(h,i,j):
        temp = h[i]
        h[i] = h[j]
        h[j] = temp
    j
    def buildMaxStack(stack,start,n): #根据stack构建大根堆,从i到j排序
        # n = len(stack)-1
        i = n//2-1
        while i >=0:
            if stack[i] > max([stack[2*i+1],stack[2*i+2]]):
                pass
            else:
                if max([stack[2*i+1],stack[2*i+2]]) == stack[2*i+1]:
                    self.swap[stack,2*i+1,i]
                    if 2*(2*i+1)+1 > n :
                        pass
                    
                
            i-=1
        
        
        
        

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值