【剑指offer】40、最小的K个数

题目

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

思路一

基于partition,当 index正好为k的时候,就是第k大的数。时间复杂度O(n)

缺点:需要改变数组

class Solution {
public:
    int Partition(vector<int>& input, int begin, int end)
    {
        int low = begin, high = end;
        int pivot = input[low];

        while(low < high)
        {
            while( low < high && pivot<=input[high])
            {
                high--;
            }
            input[low] = input[high];
            while(low < high && pivot >= input[low])
            {
                low++;
            }
            input[high] = input[low];
        }
        input[low] = pivot;
        return low;
    }

    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        int len=input.size();
        if(len == 0 || k > len || k <= 0)
            return vector<int>();
        if(len == k)
            return input;

        int start = 0, end = len - 1;
        int index = Partition(input,start,end);
        while(index != k - 1)
        {
            if (index > k - 1)
            {
                end = index-1;
                index = Partition(input,start,end);
            }
            else
            {
                start = index+1;
                index = Partition(input,start,end);
            }
        }

        vector<int> res(input.begin(), input.begin() + k);
        return res;
    }
};

思路二

使用最大堆,存储最小的k个数字,时间复杂度为O(nlogk)。

当插入时,若该元素比容器中最大元素小,则把该元素放入。

优点:不需要更改数组,适合海量数据

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        vector<int> result;
        int len = input.size();
        if(input.empty() || k <= 0 || len < k)
            return result;

        multiset<int, greater<int>> leastNumbers; // 从大到小排序
        multiset<int, greater<int>>::iterator iterGreater; // 定义迭代器

        vector<int>::iterator iter = input.begin();
        for(; iter != input.end(); ++iter)
        {
            // 将前k个数直接插入进multiset中,注意是小于K
            if (leastNumbers.size() < k)
                leastNumbers.insert(*iter);
            else
            {
                // 因为设置的从大到小排序,故multiset中第一个位置的元素即为最大值
                iterGreater = leastNumbers.begin();

                // 如果input中当前元素比multiset中最大元素小,则替换;即保持multiset中这k个元素是最小的。
                if(*iter < *(leastNumbers.begin()))
                {
                    // 替换掉当前最大值
                    leastNumbers.erase(iterGreater);
                    leastNumbers.insert(*iter);
                }
            }
        }

        for(iterGreater = leastNumbers.begin(); iterGreater!=leastNumbers.end(); ++iterGreater)
            result.push_back(*iterGreater); // 将multiset中这k个元素输出

        return result;
    }
};

原文地址:https://www.cnblogs.com/shiganquan/p/9344759.html

时间: 2024-08-30 14:54:31

【剑指offer】40、最小的K个数的相关文章

剑指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

【剑指Offer】最小的K个数

题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4, 直接使用sort排序,然后返回前k个数: class Solution { public: vector<int> GetLeastNumbers_Solution(vector<int> input, int k) { sort(input.begin(), input.end()); vector<int> r; if(k>inp

剑指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 : h

剑指offer[29]——最小的K个数

题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 这道题目对js来讲应该是很简单了,js有自带的sort函数,我们将输入的数组进行排序之后,输出前k个数就是题目要求 的结果. function GetLeastNumbers_Solution(input, k) { if(k==0 || k>input.length){return [];} input = input.sort((a,b) => a-b);

【剑指offer】最小的k的数量

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26966159 题目描写叙述: 输入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

面试题40. 最小的k个数

面试题40. 最小的k个数 问题描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 解题思路: 这题不要直接使用 sort(arr.begin(), arr.end() ) 函数: 时间复杂度:O(n\log n)O(nlogn),其中 nn 是数组 arr 的长度.算法的时间复杂度即排序的时间复杂度. 空间复杂度:O(\log n)O(logn) ,排序所需额外的空间复杂度为 O(\log n)O(l

[剑指Offer]40.数组中只出现一次的数字

题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路 我们直到异或的性质: 任何一个数字异或他自己都等于0. 所以说我们如果从头到尾依次异或每一个数字,那么最终的结果刚好只出现一次的数字,因为成对出现的两次的数字全部在异或中抵消了. 这道题中有两个数字只出现一次.这样的话我们得到的结果就是这两个数字的异或结果.因此我们想办法把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字.这样我们就可以对这两个子数组分别异或,就能得到两个只出现一

剑指offer总结列表

num 题目 英文 链接 备注 1         2         3 数组中重复的数字       4 二维数组中的查找       5 替换空格       6 从头到尾打印链表       7 重建二叉树       8 二叉树的下一个节点       9 用两个栈实现队列       10 斐波那契额数列       11 旋转数组的最小数字       12 矩阵中的路径       13 机器人的运动范围       14 剪绳子       15 二进制中1的个数      

剑指offer速查表

3.数组中重复数字:每个位置放置数字与下标对应相等 O(n) 4.二维数组中的查找:左下角开始比较 O(m+n) (微软) 5.替换空格:python直接替换 6.从尾到头打印链表:python insert函数 xxx7.重建二叉树:前序中序遍历特点递归 xxx8.二叉树的下一个节点:根据中序遍历特点,按有无右子树分情况讨论 9.两个栈实现队列:栈的特点 10.斐波那契数列:递归思想,循环方法自下而上计算 O(n) (oppo) 11.旋转数组最小数字:二分查找,考虑left,right,mi