当需要在无需列表中寻找第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中查找。

下面是代码实现:

package disorder_List;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random; public class TestDisorder {
static public int cmpcnt = 0; public static void main(String[] args) {
testFramework(); } public static int partion(ArrayList<Integer> A,int low,int high){
int pivotkey=A.get(low); while(low<high){
while(low<high&&A.get(high)>=pivotkey)
high--;
A.set(low, A.get(high));
cmpcnt++;
while(low<high&& A.get(low)<pivotkey)
low++;
A.set(high, A.get(low));
cmpcnt++;
}
cmpcnt++;
A.set(low, pivotkey);
return low;
} public static int findMinK(ArrayList<Integer> array, int k, int l, int r) {
// Implement here
if(l<=r){
int pivotloc=partion(array, l, r);
if(pivotloc==k-1){
return array.get(pivotloc);
}
else if(pivotloc<(k-1)){
return findMinK(array, k,pivotloc+1,r);
}
else{
return findMinK(array, k,l,pivotloc-1);
}
}else
{
return -1;
} } public static int findMinK(ArrayList<Integer> array, int k){
Collections.sort(array);
return array.get(k-1);
} private static void testFramework() {
ArrayList<Integer> a = new ArrayList<Integer>();
for (int j=2;j<8;j++){
a.clear(); for (int i=0;i<(int)Math.pow(10, j);i++){
a.add(i);
}
System.out.println("nn"+a.size()+" Elementsnn");
double slow=0;
double fast=0; for (int i = 0; i < 2; i++) {
cmpcnt = 0;
Collections.shuffle(a); int k = (int)(Math.random()*(Math.pow(10, j)-1))+1; System.out.println("test run number: " + i + " find: " + k); long start = System.currentTimeMillis();
int resulta = findMinK(a, k, 0, a.size()-1);
long end = System.currentTimeMillis();
long smarttime=(end-start);
fast = fast + smarttime;
System.out.println("SMART ALGO t --- time in ms: " + smarttime + " comparisons: "
+ cmpcnt);
start = System.currentTimeMillis();
int resultb=findMinK(a, k);
end = System.currentTimeMillis();
long slowtime = (end-start);
System.out.println("WITH SORTING t --- time in ms: " + slowtime); slow = slow + slowtime;
}
System.out.println("sorting (="+slow+"ms) is " +slow/fast + " times slower than smart algo (="+fast+"ms)");
}
}
}

以下是部分输出结果:

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. INNO SETUP 获得命令行参数

    原文 http://www.cnblogs.com/ahuo/archive/2009/07/30/1534998.html );           Result := CmdLine;       ...

  2. JTextPane 的 undo 、 redo

    实现文本框输入内容的单条记录撤销,重做,通过按钮实现 以及通过JList的多条撤销.重做操作(类似PS) 昨天还在为自己写不出代码怎么办而伤心,没想到今天上午就实现了,并且还完善了功能: 可以在撤销一 ...

  3. [置顶] Oracle GoldenGate 系列:使用 Oracle ASM API DBLOGREADER 时遇 ora-01031 错误

    今天在自己新搭建的 Oracle ACFS 文件系统上测试 GoldenGate ,启动 extract 进程报如下错误: 2013-08-27 14:58:39  ERROR   OGG-00446 ...

  4. 20个Linux命令及Linux终端的趣事

    20个Linux命令及Linux终端的趣事 . 命令:sl (蒸汽机车) 你可能了解 ‘ls’ 命令,并经常使用它来查看文件夹的内容.但是,有些时候你可能会拼写成 ‘sl’ ,这时我们应该如何获得一些 ...

  5. [转]linux下IPTABLES配置详解

    如果你的IPTABLES基础知识还不了解,建议先去看看.开始配置我们来配置一个filter表的防火墙.(1)查看本机关于IPTABLES的设置情况[root@tp ~]# iptables -L -n ...

  6. 中国省市位置描述JSON数据

    数据包括:省.市.区县的行政编码,以及经纬度位置. {}对象的属性描述,如:{"no":"450400","latlng":"23 ...

  7. javacript 面向对象

    1.对象 使用Object创建对象 var p = new Object(); p.name = 'jason'; p.sayName = function(){ alert(this.name); ...

  8. Python学习笔记10-Python MysqlHelper ,MySql 辅助类

    自己写了一个MySql辅助类,有需要的拿走: #--encoding:utf-8-- # import MySQLdb class MySQLHelper: myVersion=0.1 def __i ...

  9. android笔记1——开发环境的搭建

    Long Long ago...已经成为了历史,我还是要说出一个真相:早年前,那时候,android还不被大众所认知的时候,当然开发人员也没不像如今那样趋于饱和状态.一位大牛前辈,也是我的学长,那时候 ...

  10. ecside使用笔记(1)

    1. 部分属性描写叙述: 属性: tableId 描写叙述:  设置列表的唯一标识,默觉得"ec",当一个页面内有多个ECSIDE列表时,必须为每一个列表指定不同的 tableId ...