目录:
1、引子
2、排序解决法
3、类快排解法
4、最小堆解法

1、引子

日常编码中,常见遇到这样的问题,“寻找最大的数”,此问题非常容易,可暴力直接遍历找出,也可使用分冶策略找出最大值(详见分冶算法)。

本文中需要寻找第k大的数,笔者目前想到3个方法可解决它。

2、排序解决法

如果是一个有序数组,那么寻找第k的大数则相当简单了,且效率为1。数组排序算法中相对较优的算法为快速排序,效率为N*lgN,将数组从到到小排列,第k大的数则为array[k-1]。

快排的思想为,从数组中取任意一个值key,将大于key的值放在key右边,小于key的值放在key左边。key的左边和右边则都是有序的了,然后递归key左边的子数组和key右边的子数组,直到每个子数组长度为1,此时,整个数组均有序了。

代码如下

public static int partition(int[] array, int left, int right) {int k = array[left];int i = left;int j = right;while (j > i) {while (array[j] < k && j > i) {j--;}if (j > i) {array[i] = array[j];i++;}while (array[i] > k && j > i) {i++;}if (j > i) {array[j] = array[i];j--;}}array[i] = k;return i;
}public static void quickSort(int[] array, int left, int right) {if (left >= right) {return;}int i = partition(array, left, right);quickSort(array, left, i - 1);quickSort(array, i + 1, right);
}

本文中快排略有差异,是按从大到小顺序排列。
快排的partition算法有两种写法,具体可查看快速排序及主定理。此解法效率为N*lgN

3、类快排解法

由于只要求找出第k大的数,没必要将数组中所有值都排序。

快排中的partition算法,返回key在数组中的位置,如果key的位置正好等于k-1,那么问题则得到解决,如果key的位置不等于k-1,可使用递归查找对应子数组。直到key的位置等于k-1,则找对问题的解。

public static int findK(int[] array, int left, int right, int k) {int i = partition(array, left, right);if (i == k - 1) {return array[k - 1];} else if (i > k - 1) {return findK(array, left, i - 1, k);} else if (i < k - 1) {return findK(array, i + 1, right, k);}return 0;
}

此解法的效率值为N*lgK,由于K是常数,所以此解法效率值为N,优于排序解法

4、最小堆解法

最小堆是一种特殊的数组结构,它实质是一个完全二叉树,且树中子节点的值均大于父节点的值,详见 堆排序及优先队列。

考虑到只需要找到第k大的数,构造一个大小为k的最小堆,堆中根节点为最小值。如果数组中最大的几个数均在堆中,那么堆中根节点的值就是问题的解。

构造最小堆

public static void maxHeapify(int[] array, int size, int i) {int left = 2 * i + 1;int right = 2 * i + 2;int small = i;if (left < size) {if (array[small] > array[left]) {small = left;}}if (right < size) {if (array[small] > array[right]) {small = right;}}if (small != i) {int temp = array[small];array[small] = array[i];array[i] = temp;maxHeapify(array, size, small);}
}public static void buildHeap(int[] array, int size) {for (int i = size - 1; i >= 0; i--) {maxHeapify(array, size, i);}
}

最小堆已构造完成,将数组中剩余的值与根节点相比,大于根节点的值则将根节点的值与之交换,同时维护最小堆的特性,遍历结束,则根结点即为问题的解。

public static int findKByHeap(int[] array, int k) {buildHeap(array, k);for (int i = k + 1; i < array.length; i++) {if (array[i] > array[0]) {int temp = array[i];array[i] = array[0];array[0] = temp;maxHeapify(array, k, 0);}}return array[0];
}

代码地址:https://github.com/okunu/DataStructure ,欢迎访问本人的github

作者:某昆
链接:https://www.jianshu.com/p/33ee33ce8699
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

【算法】寻找第k大的数相关推荐

  1. 算法-寻找第K大的数的方法总结

    转载:http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 解法3: void findKthBigger(vector<i ...

  2. 面试官:海量无序数据,寻找第 K 大的数,越快越好

    最近在参加阿里云举办的<第三届数据库大赛创新上云性能挑战赛--高性能分析型查询引擎赛道>,传送门: https://tianchi.aliyun.com/competition/entra ...

  3. 海量无序数据寻找第 K 大的数

    前言 最近在参加阿里云举办的<第三届数据库大赛创新上云性能挑战赛--高性能分析型查询引擎赛道>,传送门:https://tianchi.aliyun.com/competition/ent ...

  4. java中二叉树中第k大的数,寻找第k大的数

    目录: 1.引子 2.排序解决法 3.类快排解法 4.最小堆解法 1.引子 日常编码中,常见遇到这样的问题,"寻找最大的数",此问题非常容易,可暴力直接遍历找出,也可使用分冶策略找 ...

  5. 快速排序 寻找第K大的数

    对于海量不确定数据,可采用维护大小为K的最小堆不断更新前K大的数 但对于数量有限的数组,可采用快速排序的思想寻找第K大的数,时间复杂度为O(lgN) 即快排之后, 若K刚好为基准点下标,那么返回基准点 ...

  6. 算法_第k大的数_快排(leetcode215,java)

    文章目录 前言 一.题目描述 二.思路 三.代码实现 前言 1.(Math.random()(x-y))+y // Math.random()(x-y+1)+y; 随机数x~y 2.递归 3.三目运算 ...

  7. [转] 寻找第k大的数

    原文地址:http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 今天看算法分析是,看到一个这样的问题,就是在一堆数据中查找到第k个 ...

  8. c++求区间第k大数_寻找第K大的数的方法总结

    今天看算法分析是,看到一个这样的问题,就是在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,当然,解决这个问题的方法很多,本人在网上搜索了一番,查找到以 ...

  9. 寻找第k大的数的方法总结

    转自:http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 今天看算法分析是,看到一个这样的问题,就是在一堆数据中查找到第k个大的 ...

最新文章

  1. jquery的live方法
  2. 清理系统垃圾文件的常用脚本
  3. C++学习之路(一)
  4. C语言简单的练习题目——牛生牛
  5. Django与jQuery通信;Django前后端传值
  6. 面试题系列(9):对前端界面工程师这个职位是怎么样理解的?
  7. 余承东吐槽苹果续航;微软 IE 浏览器被曝漏洞;React Native 0.61.0 发布 | 极客头条...
  8. 免费HTTP数据抓包Fiddler2[4.6.1.2]以及显示中文包内容的方法
  9. 关于winpcap发包速度低的问题
  10. 商务与经济统计++原书第12版+[(美)安德森著][机械工业出版社][2015.07][515页][13854037]第一章读书笔记
  11. 使用nginx配置二级域名
  12. opencv批量修改图片分辨率
  13. java for步长_Velocity模板循环支持自定义步长
  14. 外包php技术,php外包
  15. postgresql的下载与安装
  16. 【Auto.JS】Autojs官方提取文档使用说明函数 (1)
  17. QQ群创建者和管理员
  18. html文本框打tab,HTML标签textarea支持tab键
  19. [渝粤教育] 中国矿业大学 中国传统手工艺与文化创意设计 参考 资料
  20. 新增linux驱动并重新编译内核,【转】配置并编译内核[更新到linux-2.6.29.2]

热门文章

  1. 1,3,4,6-四-O-乙酰基-2-叠氮-2-脱氧-α-D-吡喃半乳糖/cas:67817-30-5
  2. win10睡眠锁定计算机,win10如何设置电脑的固定时间之后自动睡眠呢?
  3. 联想笔记本安装ubuntu,无线网卡被禁用的问题及解决方法
  4. 开始上班了,却不知道要做什么
  5. K折交叉验证与模型评估
  6. 3.1 计算机视觉的发展和卷积神经网络概要(百度架构师手把手带你零基础实践深度学习原版笔记系列)
  7. 如何把word翻译成中文,文档翻译免费方法这里学
  8. 阿里云ECS云服务器选型教程
  9. Vijos P1369难解的问题
  10. Lichee Zero SPI Flash编译实战记录