当需要在无需列表中寻找第k小的元素时,一个显然的方法是将所有数据进行排序,然后检索k个元素。这种方法的运行时间为O(n log(n))。

无序列表调用分区函数将自身分解成两个子表,其长度为i和n-i。第一个列表中的第一个i元素(不一定排序),当i与k进行比较时需在第一或第二个子列表中搜索元素。

使用findMinK(ArrayList<Integer>array, int k, int i, int r)实现,同时使用下面testframe代码测试。在函数中可增加全局变量cmpcnt,在列表中利用分区函数交换元素时计数。

对findMinK函数的实现,利用了快排的思想:

先从n个元素中找一个任意分界点,设为m,假设m在列表中的位置是i

先从n个元素中随便寻找一个数m作为分界点,m在列表中的位置为i

当 i = k时,m就是我们要寻找的第k小的数;

当 i > k时,我们就从1~i-1中查找;

当 i < k时,就从i+1~n中查找。

下面是代码实现:

  1. package disorder_List;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.Random;
  6.  
  7. public class TestDisorder {
  8. static public int cmpcnt = 0;
  9.  
  10. public static void main(String[] args) {
  11. testFramework();
  12.  
  13. }
  14.  
  15. public static int partion(ArrayList<Integer> A,int low,int high){
  16. int pivotkey=A.get(low);
  17.  
  18. while(low<high){
  19. while(low<high&&A.get(high)>=pivotkey)
  20. high--;
  21. A.set(low, A.get(high));
  22. cmpcnt++;
  23. while(low<high&& A.get(low)<pivotkey)
  24. low++;
  25. A.set(high, A.get(low));
  26. cmpcnt++;
  27. }
  28. cmpcnt++;
  29. A.set(low, pivotkey);
  30. return low;
  31. }
  32.  
  33. public static int findMinK(ArrayList<Integer> array, int k, int l, int r) {
  34. // Implement here
  35. if(l<=r){
  36. int pivotloc=partion(array, l, r);
  37. if(pivotloc==k-1){
  38. return array.get(pivotloc);
  39. }
  40. else if(pivotloc<(k-1)){
  41. return findMinK(array, k,pivotloc+1,r);
  42. }
  43. else{
  44. return findMinK(array, k,l,pivotloc-1);
  45. }
  46. }else
  47. {
  48. return -1;
  49. }
  50.  
  51. }
  52.  
  53. public static int findMinK(ArrayList<Integer> array, int k){
  54. Collections.sort(array);
  55. return array.get(k-1);
  56. }
  57.  
  58. private static void testFramework() {
  59. ArrayList<Integer> a = new ArrayList<Integer>();
  60. for (int j=2;j<8;j++){
  61. a.clear();
  62.  
  63. for (int i=0;i<(int)Math.pow(10, j);i++){
  64. a.add(i);
  65. }
  66. System.out.println("nn"+a.size()+" Elementsnn");
  67. double slow=0;
  68. double fast=0;
  69.  
  70. for (int i = 0; i < 2; i++) {
  71. cmpcnt = 0;
  72. Collections.shuffle(a);
  73.  
  74. int k = (int)(Math.random()*(Math.pow(10, j)-1))+1;
  75.  
  76. System.out.println("test run number: " + i + " find: " + k);
  77.  
  78. long start = System.currentTimeMillis();
  79. int resulta = findMinK(a, k, 0, a.size()-1);
  80. long end = System.currentTimeMillis();
  81. long smarttime=(end-start);
  82. fast = fast + smarttime;
  83. System.out.println("SMART ALGO t --- time in ms: " + smarttime + " comparisons: "
  84. + cmpcnt);
  85. start = System.currentTimeMillis();
  86. int resultb=findMinK(a, k);
  87. end = System.currentTimeMillis();
  88. long slowtime = (end-start);
  89. System.out.println("WITH SORTING t --- time in ms: " + slowtime);
  90.  
  91. slow = slow + slowtime;
  92. }
  93. System.out.println("sorting (="+slow+"ms) is " +slow/fast + " times slower than smart algo (="+fast+"ms)");
  94. }
  95. }
  96. }

以下是部分输出结果:

sorting (=3.0ms) is 3.0 times slower than smart algo (=1.0ms)

sorting (=24.0ms) is 12.0 times slower than smart algo (=2.0ms)

sorting (=41.0ms) is 8.2 times slower than smart algo (=5.0ms)

sorting (=401.0ms) is 4.773809523809524 times slower than smart algo (=84.0ms)

....

可明显看出该方法的优势。

查询无序列表中第K小元素的更多相关文章

  1. ch1_5_2求无序序列中第k小的元素

    import java.util.Arrays; import java.util.PriorityQueue; public class ch1_5_2求无序序列中第k小的元素 { public s ...

  2. 有序矩阵中第k小元素

    有序矩阵中第k小元素 题目: 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 看到有序就会想 ...

  3. dfs 二叉树中序遍历迭代解法——求解BST中第k小元素

    BST中第K小的元素 中文English 给一棵二叉搜索树,写一个 KthSmallest 函数来找到其中第 K 小的元素. Example 样例 1: 输入:{1,#,2},2 输出:2 解释: 1 ...

  4. 找出数组[1...n]中第k小元素

    //问题描述: 试编写一个算法,使之能够在数组L[1...n]中找出第k小的元素(即从小到大排序后处于第k个位置的元素) #include <stdio.h> // 结合快排思想,查找第5 ...

  5. 快速排序-无序数组K小元素

    13:07:382020-03-10 11:16:13 问题描述: 找到一个无序数组中第K小的数 样例 1: 输入: [3, 4, 1, 2, 5], k = 3 输出: 3 样例 2: 输入: [1 ...

  6. 【Leetcode 堆、快速选择、Top-K问题 BFPRT】有序矩阵中第K小的元素(378)

    题目 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ [ 1, 5, 9], [ ...

  7. [LeetCode] Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素

    Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth ...

  8. [Swift]LeetCode378. 有序矩阵中第K小的元素 | Kth Smallest Element in a Sorted Matrix

    Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth ...

  9. Leetcode 378.有序矩阵中第k小的元素

    有序矩阵中第k小的元素 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素.请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ [ 1, ...

随机推荐

  1. How to delete the icons of Win7 desktop shortcuts

    1. Copy the following bat code in txt type file, 2. save it as file extension type bat, run it as ad ...

  2. Delphi在Webbrowser上绘制图像

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  3. Boost库学习之旅入门篇

    学习及使用Boost库已经有一段时间了,Boost为我的日常开发中带来了极大的方便,也使得我越来越依赖于boost库了.但boost功能太多,每次使用还是得翻看以前的 资料,所以为了以后可以更方便的使 ...

  4. Unix/Linux环境C编程入门教程(22) C/C++如何获取程序的运行时间

    1.问:知道程序运行时间我们可以做什么? 在<C++应用程序性能优化>一书中,如果大家读过相信大家一定对性能优化这一块非常上心,文中总是对优化前后的时间对比非常直观给我们一个感受. 那么我 ...

  5. linux脚本实例之while

    写一个脚本,执行后,打印一行提示“Please input a number:",要求用户输入数值,然后打印出该数 值,然后再次要求用户输入数值.直到用户输入"end"停 ...

  6. Frameset标签

    Frameset标签不能在body中设置. <!DOCTYPE html> <html> <head> <title>框架标签</title> ...

  7. fabric 安装及使用

    官网地址 1.安装 pip install fabric 依赖 Paramiko .PyCrypto库 以下依赖肯能要手动安装 #安装 pycrypto 密码库pip install pycrypto ...

  8. hdu 1010 Tempter of the Bone(dfs暴力)

    Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, ...

  9. windows+Ubuntu双系统 windows引导修复

    我的博客:http://blog.csdn.net/muyang_ren 装完windows+Ubuntu麒麟双系统后,发现引导是Ubuntu的. Ubuntu的引导是GRUP windows的引导是 ...

  10. 【MFC学习笔记-作业5-小数据库】【单选框,复选框,滚动条,列表框】

    界面已经实现完毕. 要完成的操作就是1.性别分组(2选1) 2.属性勾选 3.年龄通过滚动条调整 4.职称通过下方的列表框选择 5.输入姓名 6.存入左方的列表框 7.当选择左方列表框的人时,可以显示 ...