问题:找出一个数组里面前K个最大数。

解法一(直接解法):

对数组用快速排序,然后直接挑出第k大的数。这种方法的时间复杂度是O(Nlog(N))。N为原数组长度。

这个解法含有很多冗余,因为把整个数组都排序了,而实际上我们不需要这样做。

解法二(K数组排序):

首先,创建一个长度为K的空数组。从原数组中先挑出K个数进行排序并放到这个空数组中。这一步的时间复杂度是O(Klog(K))。

接着,从剩下的N-K个值中,依次遍历并与上面数组的末尾的数(即里面的最大数)相比较,并插入到合适位置,需要执行(N-K)步。

总平均时间复杂度是O(Klog(K)×(N-K))。

另外,如果采用最大堆或红黑树的方法来调整插入删除K数组,时间复杂度是O(log(K)),总时间复杂度是O(Nlog(K))。

解法三(递归法):

当K值非常大或非常接近N的时候,那么上面的两种解法的时间复杂度都会显著增大,这就需要有更好的方法来应对:直接划定中值区间,通过比较的方法,找到第K个数所在的数值区间,然后二分搜索递归下去。

假设N=100万,K=50万的情况。

先选取一个中值元素(该中值是否合理将影响到算法效率,其原因同快速排序),然后将大于等于该数的元素放到其右侧,小于该数的放到左侧。如7 4 6 8 0 -1,选取6作为中值元素,则结果应该为4 0 -1 6 8 7,接下来比较K值和现在的中值元素6所在索引(3)。
如果K小于索引3,则处于包括中值元素在内的右边的元素即是前K个最大数中的前(3(索引) - K + 1)个最大数,予以保存,同时需在索引0 ~ 2间再进行递归操作继续选取第K名。
如果K大于索引3,则在4 ~ 5中递归选取第K - 3(索引) - 1名即可。
还有一关键是可以为递归中的数组长度选取一临界点,小于该临界则进行全排序,而不再进行递归操作。

平均时间复杂度是O(N)。

当问题规模不是很大时,比如数组大小N很小,N为100数量级,可以不用太追求算法的高效性,因为对于问题规模不大时,上面三种算法的运行时间相差并不大,
完全可以考虑采用第一种或者第二种比较简单的实现方式。

算法题之找出数组里第K大的数的更多相关文章

  1. 前端算法题:找出数组中第k大的数字出现多少次

    题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...

  2. #7 找出数组中第k小的数

    「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...

  3. 找出整数中第k大的数

    一  问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二  举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...

  4. 215. Kth Largest Element in an Array找出数组中第k大的值

    堆排序做的,没有全部排序,找到第k个就结束 public int findKthLargest(int[] nums, int k) { int num = 0; if (nums.length &l ...

  5. (算法)两个有序数组的第k大的数

    题目: 有两个数组A和B,假设A和B已经有序(从大到小),求A和B数组中所有数的第K大. 思路: 1.如果k为2的次幂,且A,B 的大小都大于k,那么 考虑A的前k/2个数和B的前k/2个数, 如果A ...

  6. 找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数

    找出数组中出现次数超过一半的数,现在有一个数组,已知一个数出现的次数超过了一半,请用O(n)的复杂度的算法找出这个数 #include<iostream>using namespace s ...

  7. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  8. 查找数组中第k大的数

    问题:  查找出一给定数组中第k大的数.例如[3,2,7,1,8,9,6,5,4],第1大的数是9,第2大的数是8-- 思考:1. 直接从大到小排序,排好序后,第k大的数就是arr[k-1]. 2. ...

  9. 无序数组求第K大的数

    问题描述 无序数组求第K大的数,其中K从1开始算. 例如:[0,3,1,8,5,2]这个数组,第2大的数是5 OJ可参考:LeetCode_0215_KthLargestElementInAnArra ...

随机推荐

  1. 【bzoj2259】[Oibh]新型计算机 堆优化Dijkstra

    题目描述 Tim正在摆弄着他设计的“计算机”,他认为这台计算机原理很独特,因此利用它可以解决许多难题. 但是,有一个难题他却解决不了,是这台计算机的输入问题.新型计算机的输入也很独特,假设输入序列中有 ...

  2. android应用打前需要准备些啥?

    发布之前我们需要准备的东西 参考了google官方和结合国内开发经验 1) 用户协议(本地.网络.API) 2) 签名文件(用于为APP加密,唯一标签) 3) 程序图标(第一个面对用户,准备不同的但合 ...

  3. 实现一个可配置的java web 参数验证器

    当使用java web的servlet来做接口的时候,如果严格一点,经常会对请求参数做一些验证并返回错误码.我发现通常参数验证的代码就在servlet里边,如果参数不正确就返回相应的错误码.如果接口数 ...

  4. echart模块化单文件引入

    echart模块化单文件引入百度上面是推荐这样使用.今天看了一下,做了个Demo. 文件结构如下:

  5. 转:Scipy入门

    Scipy入门 转:http://notes.yeshiwei.com/scipy/getting_started.html 本章节主要内容来自 Getting Started .翻译的其中一部分,并 ...

  6. CentOS ACL

    ACL:访问控制列表(Access Control List). 一般来说权限是针对某一类用户设置的.例如:一个文件只有拥有者.组.其他用户三种设置方式,如果希望对某个指定的用户进行单独的权限控制,就 ...

  7. 【题解】51nod1967 路径定向

    第一次写欧拉回路,实际上只要dfs下去就可以了,反正每条边都是要遍历一遍的…… 关键有两个性质:1.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图.2.一个有向图存在欧拉回路 ...

  8. BZOJ4584 & 洛谷3643 & UOJ204:[APIO2016]划艇——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4584 https://www.luogu.org/problemnew/show/P3643 ht ...

  9. BZOJ1834:[ZJOI2010]网络扩容——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1834 https://www.luogu.org/problemnew/show/P2604#sub ...

  10. BZOJ2553 [BeiJing2011]禁忌 【AC自动机 + dp + 矩乘优化】

    题目链接 BZOJ2553 题解 话说在前,此题卡精度,最好开long double 先建\(AC\)自动机 求期望,逆着求,设\(f[i][j]\)为长度为\(i\)的串,当前匹配AC自动机\(j\ ...