每日一题:查找前k个最小值

查找前k个最小值最直接的方式是遍历输入数组k遍,每次找出剩下输入中的最小值,每次查找过程中采用交换的策略,这样程序运行结束原数组的前k个数就是按顺序排列的前k个最小数,第二种思路是维护一个具有k个元素的查找树(初始化为输入数组的前k个数),对输入数组的后续每个元素a,将其与查找树的最大数b比较,如果a>=b,则什么也不做,如果a < b,则将b删除,再将a插入到查找树中,如此即可在O(n+klogn)时间内找到输入数组中的前k个最小值。第三种思路是在原数组上运行k遍初始化最小堆算法,第四种思路,如果输入是整数,则可以使用位图数据结构。下面是第二种思路的实现:

#include "stdafx.h"

#include <set>
#include <iostream>

using namespace std;

bool find_min_k(int input[],int result[],int input_count,int output_count)
{
    if(input_count < output_count) return false;
    set<int> s;
    for (int i = 0; i < output_count; ++i)
    {
        s.insert(input[i]);
    }
    for (int i = output_count; i < input_count; ++i)
    {
        set<int>::iterator tempIt = --s.end();
        if(input[i] < *tempIt)
        {
            s.erase(tempIt);
            s.insert(input[i]);
        }
    }
    int i = 0;
    for (set<int>::iterator it = s.begin(); it != s.end(); ++it)
    {
        result[i++] = *it;
    }
    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int myarray[] = {10,6,15,4,8,1,17,14,5,13,7,11,9,12,16};
    int m = 15;
    int n = 7;
    int *result = new int[n];
    if(find_min_k(myarray,result,m,n))
    {
        for (int i = 0; i < n; ++i)
        {
            cout<<result[i]<<endl;
        }
    }
    return 0;
}

时间: 2024-08-05 06:27:55

每日一题:查找前k个最小值的相关文章

在N个数中查找前K个最大数

在N个数中查找前K个最大数,主要利用小堆的特点,小堆,是根节点元素小于左右子树元素,查找前K个最大数,先将N个数中的前K个数生成小堆,接着,依次将N中的剩余的数与小堆的根节点相比,如果大于根节点,则根节点换为这个数,再将堆进行生成小堆,依次直到N中无剩余,代码如下 #define N 10000 #define K 100 void Create(int top[],int parent) { int child = 2 * parent + 1; while (child < K) { if

基于快速排序的查找前K个最大数

快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left<right){ let mid=partition(a,left,right);//选出key下标 quickSort(a,left,mid-1);//对key的左半部分排序 quickSort(a,mid+1,right)//对key的右半部份排序 } } function partition(a,left,right){ let key=a[left];//一开始

此题要求前k小答案,我们首先把k个inf加入小根堆

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#define mp make_pair#define pa pair<int,int>#define M 500005#include <queue>#define inf 0x3f3f3f3f#

在集合中查找前k个最小的数

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define SIZE 10 5 6 int * k_thSmallest(int * arr, int len, int k_len); 7 8 void find(int* arr, int low, int high, int k_len); 9 10 void swap(int * a, int *b); 11 12 void printArr(int * arr, int le

从海量数据中查找出前k个最小或最大值的算法(java)

现在有这么一道题目:要求从多个的数据中查找出前K个最小或最大值 分析:有多种方案可以实现.一.最容易想到的是先对数据快速排序,然后输出前k个数字.   二.先定义容量为k的数组,从源数据中取出前k个填充此数组,调整此数组的最大值maxValue到首位,然后对剩下的n-k个数据迭代,对于每个遍历到的数字x,如果x < maxValue,用x把maxValue替换掉,然后调整数组最大值的位置. 三.基于二的思路,维护容量为k的堆,从源数据中取出前k个填充实例化堆,调整此堆中的最大值maxValue到

寻找数组中第k个最小值,使用快速排序

快速排序的一个特点是:每一次分区(partition)操作之后,就有一个元素被放在了数组的最终位置,在以后的排序过程中该元素位置不会变动: 利用这个特点我们可以将快速排序稍加改造来寻找第k个最小值,假设在一次分区操作之后中枢(pivot)的位置在k之前,那么我们下次只需要在中枢的后面进行查找:如果中枢的位置在k之后,那么我们下次只需要在中枢之前进行查找,直到中枢等于k为止. 我们知道快速排序的时间复杂度为O(nlgn),因为在寻找第k个最小的值时,我们只需要在中枢的一侧进行查找,所以通常来说这个

老男孩教育每日一题-第101天-如何通过端口查找出进程所在目录?

参考答案: 第一步-找到端口对应的进程的号 [[email protected] ~]# ss -lntup |grep :22 tcp    LISTEN     0      128                   :::22                   :::*      users:(("sshd",1467,4)) tcp    LISTEN     0      128                    *:22                    *:*

老男孩教育每日一题-2017年5月16日-说说{}与[]这两个符号有什么区别?

1.题目 2.参考答案 这两个看似简单的符号,其实内容还不少.我们一起来看看. 2.1 通配符中 通配符在linux中通常用来匹配/找文件名或目录名.最常用的就是 ls -l *.txt显示出所有以.txt结尾的文件. 2.1.1  {} 花括号,大括号,生产序列 [[email protected] regular]# echo {a..z} {0..9} a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8

老男孩教育每日一题-2017年5月18日-说说|(管道)与|xargs(管道xargs)的区别

1.题目 2.参考答案 find  |xargs ls -ld##把前一个命令的结果,通过管道传递给后面的命令(ls -ld),传递的是文件名find  | 命令    ##把前一个命令的结果,通过管道传递给后面的命令,传递的是普通的文本,文字,字符串 测试方法1-sed -i参数 sed -i参数修改文件内容,后面必须要加上文件名否则会报错.no input file [[email protected] ~]# find  /oldboy/ -type f  -name "*.sh"