【Python】剑指offer-面试题40 最小的K个数

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

# -*- coding:utf-8 -*-
import random
import heapq
class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        n = len(tinput)
        if n == 0 or k > n or k <= 0:
            return []
        start, end = 0, n - 1
        index = self.partition(tinput, start, end)
        while index != k - 1:
            if index > k - 1:
                end = index - 1
                index = self.partition(tinput, start, end)
            else:
                start = index + 1
                index = self.partition(tinput, start, end)

        return tinput[:k]
        # 牛客上面顺序不对还通不过,最后还来个排序
        # output = sorted(tinput[:k])  # 顺序不对还通不过
        # return output

    def partition(self, tinput, start, end):
        index = random.randint(start, end)
        # index = (start + end) // 2
        tinput[index], tinput[end] = tinput[end], tinput[index]
        small = start - 1
        for index in range(start, end):
            if tinput[index] < tinput[end]:
                small += 1
                if small != index:
                    tinput[index], tinput[small] = tinput[small], tinput[index]
        small += 1
        tinput[end], tinput[small] = tinput[small], tinput[end]
        return small
    # 内置函数操作有点sao哈
    def GetLeastNumbers_Solution2(self, tinput, k):
        n = len(tinput)
        if n == 0 or k > n or k <= 0:
            return []
        return heapq.nsmallest(k, tinput)

if __name__=='__main__':
    s = Solution()
    input = [4,5,1,6,2,7,3,8]
    k = 4
    print(s.GetLeastNumbers_Solution2(input, k))

剑指offer在中处理海量数据,无法一次性把所有数据读入内存中的方法:

创建一个大小为k的数据容器来存储最小的k个数字,接下来每次从输入的n个整数中读入一个数。如果容器中已有的数字少于k个,则直接把这次读入的整数放入容器中;如果容器中已有k个数字了,即容器已满,此时找出k 个数中的最大值,与待进入的值进行比较,若比当前已有最大值小,则替换;

如何找容器中k个数的最大值,采用最大堆实现,因此可以在O(1)的时间内获取最大值,在O(log(k))的时间内完成删除和插入操作;

你可能感兴趣的:(剑指offer)