剑指offer:最小的k个数

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

# -*- coding: utf-8 -*-
# @Time         : 2019-07-08 21:09
# @Author       : Jayce Wong
# @ProjectName  : job
# @FileName     : getLeastNumbers.py
# @Blog         : https://blog.51cto.com/jayce1111
# @Github       : https://github.com/SysuJayce

class Solution:
    """
    从数组中寻找最小的k个数字,一般来说最直接的做法就是先将这个数组排序,然后取最小的k个数字即可。
    但是这样做的时间复杂度为O(nlogn)

    解法1:
    借鉴快排中partition()的做法,因为partition()每次可以确定一个下标的正确元素,并保证其左右与其
    大小关系有序。所以只要我们通过partition()确定了下标为k-1的元素,那么其左边都是小于该元素的。
    时间复杂度为O(n)

    解法2:
    可以维护一个容量为k的容器,然后遍历整个数组,如果遇到比容器中最大值要小的元素,那么就将这个元素
    替换容器中的最大值。时间复杂度为O(nlogk)
    """
    def GetLeastNumbers_Solution1(self, tinput, k):
        if k <= 0 or k > len(tinput):
            return []

        ans = tinput[:k]
        for i in range(k, len(tinput)):
            if tinput[i] < max(ans):
                ans.remove(max(ans))
                ans.append(tinput[i])

        return sorted(ans)

    def GetLeastNumbers_Solution2(self, tinput, k):
        def partition(begin, end):
            pos = begin
            for i in range(begin, end):
                if tinput[i] < tinput[end]:
                    tinput[i], tinput[pos] = tinput[pos], tinput[i]
                    pos += 1
            tinput[end], tinput[pos] = tinput[pos], tinput[end]
            return pos

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

        start, stop = 0, len(tinput) - 1
        idx = partition(start, stop)
        while idx != k - 1:
            if idx > k:
                stop = idx - 1
            else:
                start = idx + 1
            idx = partition(start, stop)

        return sorted(tinput[: k])

def main():
    nums = [4, 5, 1, 6, 2, 7, 3, 8]
    k = 4
    solution = Solution()
    print(solution.GetLeastNumbers_Solution2(nums, k))

if __name__ == ‘__main__‘:
    main()

原文地址:https://blog.51cto.com/jayce1111/2418363

时间: 2024-10-08 00:59:27

剑指offer:最小的k个数的相关文章

剑指offer | 最小的K个数

题目描述:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 题目解析:首先想到的就是插入法,.改进一下就是前面一直保持7个有序数字.遍历剩下数组,元素若小于最大值就交换.用C++的set来解决代码就简洁多了,删除插入都是logk. 代码如下: 1 class Solution { 2 public: 3 vector<int> GetLeastNumbers_Solution(vector<int> inpu

python剑指offer最小的K个数

题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 思路: 使用快排中的partition思想. ①我们设定partition函数的哨兵为key=lists[left],在partition函数中完成一轮比较的结果是,比key大的数都在其右边,比key小的数放在其左边.完成该轮后返回其left=right时left的值. ②我们判断left的值是比k大还是小: 如果left的值比k大,说明上轮partition之

剑指Offer-29.最小的K个数(C++/Java)

题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 分析: 最先想到的是将数组升序排列,返回前k个元素.不过排序的话效率可能会较低,我们可以使用优先级队列模拟堆来处理. 模拟一个k个元素的最大堆,当堆内元素个数等于k的时候,新来的元素就要和堆顶元素去比较,如果小于堆顶元素,就删除堆顶元素,将新元素添加进堆中,由于最大堆的堆顶元素是最大元素,我们可以保持堆中元素始终是最小的几个,因为每有新的元素来,都会进行比较,最后堆

剑指Offer28 最小的K个数

包含了Partition函数的多种用法 以及大顶堆操作 1 /************************************************************************* 2 > File Name: 28_KLeastNumbers.cpp 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年08月31日 星期三 19时45分41秒 6 *******

剑指Offer--030-最小的K个数

链接 牛客OJ:最小的K个数 九度OJ:http://ac.jobdu.com/problem.php?pid=1371 GitHub代码: 030-最小的K个数 CSDN题解:剑指Offer–030-最小的K个数 牛客OJ 九度OJ CSDN题解 GitHub代码 最小的K个数 1371-最小的K个数 剑指Offer–030-最小的K个数 030-最小的K个数 题意 题目描述 输入n个整数,找出其中最小的K个数. 例如输入4,5,1,6,2,7,3,8这8个数字, 则最小的4个数字是1,2,3

29、剑指offer--最小的K个数

题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解题思路:使用multiset存储k个最小值 1)先存入k个值 2)用multiset中的最大值和当前访问数组元素比较,若小于则把该值从multiset中移除,数组元素插入 3)遍历multiset将k个值存入vector中注意事项:边界条件的判断,数组为空,k小于1,以及k大于数组元素数目 1 class Solution { 2 public: 3 vecto

剑指offer——倒数第k个节点

先走k-1步,然后判断fast有没有到空为止. /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if(head==null||k<=0) { return null; } ListNode fa

【剑指offer】 堆排序查找最小的K个数

上一篇 说了些堆的建立及其相关操作,这里看下用堆来解决数据量较大的时候,查找最小的k个数的情况.这里会用到上一篇中的函数. 我们先生存1千万个随机数,写到文件中: import random def randData(): with open('randint.txt', 'w') as fd: for i in range(1, 10000000): fd.write('%d ' %random.randint(1, 100)) if i % 100 == 0: fd.write('\r')

剑指OFFER之最小的K个数(九度OJ1371)

题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 输入: 每个测试案例包括2行: 第一行为2个整数n,k(1<=n,k<=200000),表示数组的长度. 第二行包含n个整数,表示这n个数,数组中的数的范围是[0,1000 000 000]. 输出: 对应每个测试案例,输出最小的k个数,并按从小到大顺序打印. 样例输入: 8 4 4 5 1 6 2 7 3 8 样例输出: 1 2 3 4 解题思路: 我们通过

剑指offer (30) 最小的K个数

题目:输入n个整数,找出其中最小的K个数 方法一:直接std::sort,T(n) = O(nlgn) 方法二:直接std::nth_element T(n) = O(n) 但是修改了原数组 void MinKth(std::vector<int>& num, int kth, std::vector<int>& result) { if (num.size() == 0 || || kth <= 0 || kth > num.size()) { thr