我们举例,假若从10000万个数里选出前100个最大的数据。

首先我们先分析:既然要选出前100个最大的数据,我们就建立一个大小为100的堆(建堆时就按找最大堆的规则建立,即每一个根节点都大于它的子女节点),然后再将后面的剩余数据若符合要求就插入堆中,不符合就直接丢弃该数据。

那我们现在考虑:确定是该选择最大堆的数据结构还是最小堆的数据结构呢。

分析一下:

若选用最大堆的话,堆顶是堆的最大值,我们考虑既然要选出从10000万个数里选出前100个最大的数据,我们在建堆的时候,已经考虑了最大堆的特性,那这样的话最大的数据必然在它顶端。假若真不巧,我开始的前100个数据中已经有这10000个数据中的最大值了,那对于我后面剩余的10000-100的元素再想入堆是不是入不进去了!!!所以,选用最大堆从10000万个数里选出前100个最大的数据只能找出一个,而不是100个。

那如果选用最小堆的数据结构来解决,最顶端是最小值,再次遇到比它大的值,就可以入堆,入堆后重新调整堆,将小的值pass掉。这样我们就可以选出最大的前K个数据了。言外之意,假若我们要找出N个数据中最小的前k个数据,就要用最大堆了。

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std; #include<assert.h> void AdjustDown(int* a, int parent, int size)
{
    int child = 2 * parent + 1;
    while (child < size)
    {
        if (child + 1 < size && a[child] > a[child + 1])
        {
            child++;
        }
        if (a[parent]>a[child])
        {
            swap(a[parent], a[child]);
            parent = child;
            child = 2 * parent + 1;
        }
        else
        {
            break;
        }
    }
} void Print(int* a, int size)
{
    cout << "前k个最大的数据:" << endl;
    for (int i = 0; i < size; i++)
    {
        cout << a[i] << "  ";
    }
    cout << endl;
} int* HeapSet(int*a,int N,int K)
{
    assert(a);
    assert(K > 0);
    int* arr = new int[K];
    //将前K个数据保存
    for (int i = 0; i < K; i++)
    {
        arr[i] = a[i];
    }     //建堆
    for (int i = (K-2)/2; i >=0; i--)
    {
        AdjustDown(arr,i,K);
    }      //对剩余的N-K个元素比较大小
    for (int i = K; i < N; i++)
    {
        if (arr[0]<a[i])
        {
            arr[0] = a[i];
            AdjustDown(arr, 0, K);
        }
    }     return arr;
    delete[] arr;
} void Test()
{
    int arr[] = { 12, 2, 10, 4, 6, 8, 54, 67, 25, 178 };
    int k = 5;
    int* ret = HeapSet(arr, sizeof(arr) / sizeof(arr[0]), k);
    Print(ret, k); 
} int main()
{
    Test();
    system("pause");
    return 0;
}

  

由此可以看出,时间复杂度为:K+(K-2)/2*lgn+(N-K)*lgn  -->  O(N)

空间复杂度为:K-->O(1)。

求数组前K个大的数的更多相关文章

  1. MATLAB寻找数组前k个大值

    有时候我们需要寻找数组的前k个大值并按照顺序输出, 在C语言可以通过快速排序等算法,快速求得,这里用matlab写了一个比较简单实用的程序(适用于数组长度不是特别大的情况). function [va ...

  2. [csu/coj 1080]划分树求区间前k大数和

    题意:从某个区间内最多选择k个数,使得和最大 思路:首先题目给定的数有负数,如果区间前k大出现负数,那么负数不选和更大,于是对于所有最优选择,负数不会出现,所以用0取代负数,问题便转化为区间的前k大数 ...

  3. 无序数组中第Kth大的数

    题目:找出无序数组中第Kth大的数,如{63,45,33,21},第2大的数45. 输入: 第一行输入无序数组,第二行输入K值. 该是内推滴滴打车时(2017.8.26)的第二题,也是<剑指of ...

  4. 输出数组里面第N大的数

    好像有些大公司出过面试题:找出数组里面第N大的数,当然有点变化,但本质部分是这样的. 要求是不能排序,时间复杂度不能超过O(n^2) 思路很多,我暂时就只会快排衍生的那种.如果对快速排序不太熟悉了,建 ...

  5. 快速排序及查找第K个大的数。

    本文提供了一种基于分治法思想的,查找第K个大的数,可以使得时间复杂地低于nlogn. 因为快排的平均时间复杂度为nlogn,但是快排是全部序列的排序, 本文查找第k大的数,则不必对整个序列进行排序.请 ...

  6. 认真对待每一道算法题 之 两个排序好的数组寻找的第k个大的数

    转载博客:http://www.cnblogs.com/buptLizer/archive/2012/03/31/2427579.html 题目意思:给出两个排好序的数组 ,不妨设为a,b都按升序排列 ...

  7. [经典] 在未排序数组中返回topK大的数

    解法一,排序 先从大到小快排,然后扫前K个返回 时间复杂度:O(NlogN),空间复杂度O(1) 解法二,优先队列 前K个放入优先队列中,与最小堆顶元素比较大小,若大于则删除堆顶并插入:否则跳过 时间 ...

  8. (算法)Partition方法求数组第k大的数

    如题,下面直接贴出代码: #include <iostream> using namespace std; int Partition(int* A,int left,int right) ...

  9. 【RMQ问题】求数组区间最大值,NYOJ-1185-最大最小值

    转自:http://blog.csdn.net/lilongherolilong/article/details/6624390 先挖好坑,明天该去郑轻找虐 RMQ(Range Minimum/Max ...

随机推荐

  1. Python爬取信息管理系统计算学分绩点

    试手登录了下我们学校的研究生信息管理系统,自动计算学分绩点 # -*- coding:utf-8 -*- import urllib import urllib2 import re import c ...

  2. 1+X证书Web前端开发规范手册

    一.规范目的 1.1 概述 为提高团队协作效率, 便于后台人员添加功能及前端后期优化维护, 输出高质量的文档, 特制订此文档. 本规范文档一经确认, 前端开发人员必须按本文档规范进行前台页面开发. 本 ...

  3. 局域网部署ntp时间服务器

    搭建ntp时间服务器 时间服务器配置 须切换到root用户,再进行操作 检查ntp是否安装 [root@hadoop01 ~]# rpm -qa | grep ntp 如果没有安装,须安装 [root ...

  4. SQL Server 2014:为什么数据库里的表提示“单元格是只读的”,不能修改?该如何处理?

    出现以上这种情况,首先看一下这个字段的属性“标识规范”是不是选了“是”,自增属性下是不能修改的,属于只读.

  5. vue项目打包之后样式错乱问题,如何处理

    最近公司做的这个项目,要大量修改element里面的css样式,所以项目打包之后 会出现样式和本地开发的时候样式有很多不一样,原因可能是css加载顺序有问题,样式被覆改了. 所以在mian.js里面这 ...

  6. python 自定义Iterator对象

    from collections.abc import Iterator class Company(object): def __init__(self, employee_list): self. ...

  7. 解决java,C#,php,python MD5加密不一致问题

    JAVA写法 public static String md5Base64(final String str, final String key) throws Exception { if ((nu ...

  8. IDEA帮助文档快捷键ctrl+q 查看类 方法 变量 帮助文档 注释 快捷键

    IDEA查看类 成员变量  局部变量注释快捷键,Ctrl +Q 查看帮助文档 实际项目中,通常一个类中的代码都不少,而且有很多的变量 那么如何快速知道这个变量的一些信息,比如类型,定义? 比如在第50 ...

  9. 如何配置Memcached高速缓存,加快wordpress的速度

    Memcached是什么 Memcached是一种高性能的分布式内存对象缓存系统.在动态应用,Memcached既能提高访问的速度,同时还减低了数据库的负载.DangaInteractive为提升Li ...

  10. C#刷遍Leetcode系列连载 索引

    C#刷遍Leetcode系列文章 索引 索引(陆续发布中,请保持关注) C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介 C#刷遍Leetcode面试题系列连载(2): No.38 - ...