笔试题,最后一题

查找网易云音乐中播放量最大的前K个歌曲。

换句话说,就是在数组中查找前K大元素。

大致有以下几个思路。

1.第一感觉就是对数组进行降序全排序,然后返回前K个元素,即是需要的K个最大数。

排序算法的选择有很多,考虑数组的无序性,可以考虑选择快速排序算法,其平均时间复杂度为O(NLogN)。具体代码实现可以参见相关数据结构与算法书籍。

2.观察第一种算法,问题只需要找出一个数组里面前K个最大数,而第一种算法对数组进行全排序,不单单找出了前K个最大数,更找出了前N(N为数组大小)

个最大数,显然该算法存在“冗余”,因此基于这样一个原因,提出了改进的算法二。

首先建立一个临时数组,数组大小为K,从N中读取K个数,降序全排序(排序算法可以自行选择,考虑数组的无序性,可以考虑选择快速排序算法),然后依

次读入其余N - K个数进来和第K名元素比较,大于第K名元素的值则插入到合适位置,数组最后一个元素溢出,反之小于等于第K名元素的值不进行插入操作。

只待循环完毕返回临时数组的K个元素,即是需要的K个最大数。同算法一其平均时间复杂度为O(KLogK + (N - K))。具体代码实现可以自行完成。

算法时间复杂度证明:

原问题:
顺序统计量选择问题:数组A包含N个元素,找出数组A中前K个最大数
解法二:
首先建立一个临时数组,数组大小为K,从N中读取K个数,降序全排序(可以考虑选择快速排序算法,快排平均复杂度O(KlogK)),
然后依次读入其余N - K个数进来和第K名元素比较,大于第K名元素的值则插入到合适位置,数组最后一个元素溢出,反之小于等于第K名元素的值不进行插入操作。
只待循环完毕返回临时数组的K个元素,即是需要的K个最大数。
其平均时间复杂度为O(KLogK + (N - K))。
证明:
设指示器随机变量
Xi = {A属于前K个最大数},i=K+1, K+2, ..., N;
由于数组A的N个元素分布随机,则E[Xi] = 1/N;
则依次处理其余N - K个数的时间复杂度为T(N-K) = sum(Xi*logK),i=K+1, K+2, ..., N;
(注意logK是将一个数插入到排好序的K个数的时间复杂度) 
对上式求期望,得
E[T(N-K)] = E[sum(Xi*logK),i=K+1, K+2, ..., N]
= sum(E[Xi] * logK),i=K+1, K+2, ..., N
= sum(1/n * logK),i=K+1, K+2, ..., N
= (N-K)logK/n < N-K;
综合,该算法平均时间复杂度为
T(N) = O(KLogK + (N - K))。

3.上面两种算法在N=100万,K=50万时速度都尤其“漫长“,现在提出一种更高效的算法,该算法原理和快速排序一致,但只有一个方向的递归,其平均时间

复杂度为O(N)。

先选取一个中值元素(该中值是否合理将影响到算法效率,其原因同快速排序),然后将大于等于该数的元素放到其右侧,小于该数的放到左侧。如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名即可。

还有一关键是可以为递归中的数组长度选取一临界点,小于该临界则进行全排序,而不再进行递归操作。

以上算法均是本人在书本上或者互联网上学习的算法,并非自己原创,当然部分的改动还是自我原创的。

其实当问题规模不是很大时,比如数组大小N很小,N为100数量级,可以不用太追求算法的高效性,因为对于问题规模不大时,上面三种算法的运行时间相差并不大,

完全可以考虑采用第一种或者第二种比较简单的实现方式。

在LintCode上有相关题目。

http://www.lintcode.com/en/problem/kth-largest-element/

AC的代码如下

class Solution {/** @param k : description of k* @param nums : array of nums* @return: description of return*/public int kthLargestElement(int k, int[] nums) {// write your code hereint l = 0, r = nums.length - 1;while (l < r) {int left = l, right = r;int key = nums[left];while (left < right) {while (left < right && nums[right] < key) {right--;}nums[left] = nums[right];while (left < right && nums[left] >= key) {left++;}nums[right] = nums[left];}nums[left] = key;if (left == k - 1) return nums[k - 1];else if (left > k - 1) r = left - 1;else  l = left + 1;}return nums[k - 1];}
};

网易_在数组中查找前K个元素相关推荐

  1. 在数组中查找第k个最大元素_查找数组中每个元素的最近最大邻居

    在数组中查找第k个最大元素 Problem statement: 问题陈述: Given an array of elements, find the nearest (on the right) g ...

  2. 单峰数组找最大元素C语言,查找单峰数组中的第k个元素

    给定一个n个不同元素的单峰数组A(意味着它的条目按递增顺序排列直到其最大元素,之后其元素的递减顺序),则整数p (即增加的第一部分的长度)和k(第k个最小元素)给出算法以计算在O(log n)时间中运 ...

  3. 【算法】快速选择算法 ( 数组中找第 K 大元素 )

    算法 系列博客 [算法]刷题范围建议 和 代码规范 [算法]复杂度理论 ( 时间复杂度 ) [字符串]最长回文子串 ( 蛮力算法 ) [字符串]最长回文子串 ( 中心线枚举算法 ) [字符串]最长回文 ...

  4. 如何寻找无序数组中的第K大元素?

    如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...

  5. 数组中的第K大元素问题(C++)

    数组中的第K大元素问题 问题: 在未排序的数组中找到第 k 个最大的元素.请注意,需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 约定: 假设这里数组的长度为 n. 方法一: ...

  6. C语言编程>第二十六周 ① 函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换。形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动。

    例题:函数fun的功能是:将形参b所指数组中的前半部分元素的值和后半部分元素的值对换.形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动. 例如,若a所指数组中的数据依次为:11 22 33 ...

  7. 第十四周项目一数组大折腾(1)创建一个有20个元素的整型数组,通过初始化,为数组中的前10个元素赋初值,然后通过键盘输入后10个元素的值,从前往后输出数组中元素的值,每五个元素

    问题及代码 创建一个有20个元素的整型数组,通过初始化,为数组中的前10个元素赋初值,然后通过键盘输入后10个元素的值,从前往后输出数组中元素的值,每五个元素 换一行. /*烟台大学计算机学院 201 ...

  8. java旋转数组查找某一个值_旋转数组中查找某个元素

    在一个排序的数组中,如{1,2,3,4,5,6,7},经过旋转后得到{4,5,6,7,1,2,3},当然也可以得到原数组{1,2,3,4,5,6,7},在该旋转后的数组中查找某个元素. 旋转后的数组可 ...

  9. 数组2——查找第k小元素

    在数组a的前n个元素中找出第k(1≤k≤n)小的元素,例如,数组{98, 33, 21, 102, 45, 5, 32, 11, 65, 82, 193, 321, 34, 72}中第5小的元素是33 ...

最新文章

  1. 普罗米修斯 监控_完美的分布式监控系统——普罗米修斯
  2. javascript:为string类添加三个成员,实现去左,右,及所有空格
  3. 总结:Apache架构师30条架构原则
  4. wamp编写html页面空白,Win10安装wampserver后打开localhost出现空白怎么办
  5. SAP CRM WebClient UI F4 value help is centrally implemented in CRM_THTMLB_UTIL/F4Frameset.html
  6. 全球首发|阿里云正式推出云数据库Redis6.0版本
  7. windows8.1下安装Cygwin并通过apt-cyg安装软件包
  8. 当MySQL执行XA事务时遭遇崩溃,且看华为云如何保障数据一致性
  9. 安卓linux终端 计算,5种在Linux终端中进行算术运算的方法
  10. 从时分复用、频分复用到码分复用(CDMA)
  11. Julia : WinRPM error -----待确定
  12. Graph——bfs,dfs
  13. 学习3D建模电脑配置要求
  14. 关键字深度剖析,集齐所有关键字可召唤神龙?【二】
  15. 按键精灵脚本:采集鼠标当前所在坐标的颜色
  16. pycharm新建项目环境设置详解
  17. The world与Mathon2的比较
  18. 五分钟学会用Simulink模型生成HDL代码
  19. 前端实现pdf在线预览
  20. 【2017/07】实验记录——SSSP

热门文章

  1. 这才是2019年最新资料!
  2. 关于AIX上VMO调整参数的若干说明
  3. oracle存储超长文本
  4. 不惧严寒的涩北“特种兵”
  5. 顺序查找 折半查找 二叉排序树
  6. EXCEL列乱序后内容重新对应
  7. 用python画篮球场_如何使用 Python 创建一个 NBA 得分图
  8. KTV点歌系统数据库设计文档
  9. 超级好用的cmd工具软件:Cmder
  10. c盘users在哪(c盘users在哪)