题目描述

有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。

给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。

扩展思考:如何处理数组中的重复元素?比如,对于数组a={1,3,5,2,2},第四大的元素应该是2还是1呢?

本文作这种分类:

如果第四大的元素是2,说明在处理第k大的元素时不处理重复的数据,也就是将原数组进行降序排序后,下标为k-1的元素。这种处理方法称之为“不处理重复数据方法”;

如果第四大的元素是1,说明已经忽略重复的数据了,这时候需要首先对a进行去重处理(可以用哈希表),然后再进行讨论。这种处理方法称之为“去除重复数据方法”。

下面的方法都默认为第一种。

分治法

快速排序使用了分治法的策略。它的基本思想是,选择一个基准数(一般称之为枢纽元),通过一趟排序将要排序的数据分割成独立的两部分:在枢纽元左边的所有元素都不比它大,右边所有元素都比它大,此时枢纽元就处在它应该在的正确位置上了。

在本问题中,假设有N个数存储在数组a中。我们从a中随机找出一个元素作为枢纽元,把数组分为两部分。其中左边元素都不比枢纽元大,右边元素都不比枢纽元小。此时枢纽元所在的位置记为mid。

如果右半边(包括a[mid])的长度恰好为k,说明a[mid]就是需要的第k大元素,直接返回a[mid]。

如果右半边(包括a[mid])的长度大于k,说明要寻找的第k大元素就在右半边,往右半边寻找。

如果右半边(包括a[mid])的长度小于k,说明要寻找的第k大元素就在左半边,往左半边寻找。

public class FindKth {public static void main(String[] args) {// [1,3,5,2,2],5,3int arr[] = {1,3,5,2,2};datastructure.FindKth f = new datastructure.FindKth();int result = f.findKth(arr, 5, 1);System.out.println(result);for(int t : arr){System.out.print(t+" ");}System.out.println("");}public int findKth(int[] a, int n, int k) {return find(a, 0,n-1, k);}public int find(int[] a, int start, int end, int k){// 比第一个元素大的放左边,小的放右边int p = partition(a, start, end);if(p+1 < k){return find(a, p+1,end, k);}if(p+1 > k){return find(a, start, p-1, k);}return a[p];}public int partition(int[] a, int start, int end){int i = start;int j = end + 1;int V = a[start];while(true){while(a[++i] > V){ // 直到比V小if(i>=end) break;}while(a[--j] < V){// 直到比V大if(j<=start) break;}if(i >= j)break;// 交换i,j位置的值exchange(a,i,j);}exchange(a,start,j);return j;}private void exchange(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}
}

常考数据结构与算法:查找第K大元素算法相关推荐

  1. 【数据结构与算法之美】排序(下):如何用快排思想在O(n)内查找第K大元素?

    目录 一.分治思想 二.归并排序 三.快速排序 四.归并排序与快速排序的区别 五.课后思考 一.分治思想 1.分治思想:分治,顾明思意,就是分而治之,将一个大问题分解成小的子问题来解决,小的子问题解决 ...

  2. 12 | 排序(下):如何用快排思想在O(n)内查找第K大元素?

    算法对比: 算法 时间复杂度 适合场景 冒泡排序.插入排序.选择排序 O(n2) 小规模数据 归并排序.快速排序 O(nlogn) 大规模数据 归并排序和快速排序都用到了分治思想,非常巧妙.我们可以借 ...

  3. 在两个有序链表中查找第K大元素。

    这是一次面试的时候,别人问我的,当时回答的不太好. 题目描述: 即在两个有序链表中查找第k大的元素,相等的元素做一个元素处理. {1,3,5}, {2,4,6},这是简单的情况,查找第2大的元素则是 ...

  4. 快速排序查询第k大元素C语言,快速排序和查找第K大元素

    /* 输入n个整数和一个正整数k(1<=k<=n),输出这些整数从小到大排序后的第k个(例如,k=1就是最小值).n<=10^7. 快速排序的时间复杂度为:最坏情况下:O(n^2), ...

  5. 网易_在数组中查找前K个元素

    笔试题,最后一题 查找网易云音乐中播放量最大的前K个歌曲. 换句话说,就是在数组中查找前K大元素. 大致有以下几个思路. 1.第一感觉就是对数组进行降序全排序,然后返回前K个元素,即是需要的K个最大数 ...

  6. 数组中第K大元素(java多种方式实现)

    题目描述: Leetcode215题:在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5 ...

  7. 常考数据结构与算法:输出二叉树的右视图

    题目描述 请根据二叉树的前序遍历,中序遍历恢复二叉树,并打印出二叉树的右视图 上图树的右视图为:{1,4,3,7} 做此题之前可以先做下面3道题: 1. 常考数据结构与算法:求二叉树的层序遍历 2.常 ...

  8. 常考数据结构与算法:求二叉树的层序遍历

    题目描述 给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历) 例如: 给定的二叉树是{3,9,20,#,#,15,7}, 该二叉树层序遍历的结果是 [ [3], [9,20], ...

  9. 【算法】在N个乱序数字中查找第K大的数字

    目录 1. 结论 2. 经典的几种解法 2.1 解法一:O(n*k) 2.2 解法二:O(n*logk) 2.3 解法三:O(n) 2.4 解法四:O(n*logn+k) 2.5 解法五:O(n*lo ...

最新文章

  1. 10个帮助你快速调试和排错的小技巧
  2. Xcode环境变量,Build Settings参数
  3. 制定数据丢失防范策略的六个要点
  4. Arria10_emif
  5. vba xml 怎么设置父节点_熊二做了一个xml报文处理的开源库easyxml
  6. 大量开发者会将访问token和API密钥硬编码至Android应用
  7. redis java 缓存服务器_java中对Redis的缓存进行操作
  8. android 事件反拦截
  9. 【Antlr】Antlr 在语法中嵌入任意动作
  10. mc穿越时空地图android,我的世界RPG地图穿越时空地图存档下载
  11. C# 异常类型及对应异常类
  12. [洛谷P1156][codevs1684]垃圾陷阱
  13. ROS学习(六)—— 理解ROS节点
  14. opencv Basic Drawing
  15. UnixC的第十三天
  16. 用 Unity 编写象棋游戏
  17. fastadmin表格操作
  18. 使用windows日志监控AD安全性的五大挑战
  19. python量化策略——改进的美林时钟轮动策略(三)
  20. bitlocker加密怎么解除(破解Bitlocker加密方法)

热门文章

  1. CentOS6.8 安装/升级Python2.7.x,并安装最新setuptools、pip、fabric程序总结
  2. mysql远程连接 Host * is not allowed to connect to this MySQL server
  3. 浙江大学PAT上机题解析之1009. 说反话 (20)
  4. MYSQL 取随机记录的方法
  5. JBOSS优化--比较有用的生产环境配置
  6. 细颗粒度Singleton模式实现
  7. 函数式编程与REST的思考
  8. 你不知道的JavaScript运算符
  9. 「LibreOJ β Round #4」子集
  10. (剑指Offer)面试题18:树的子结构