当需要在无需列表中寻找第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. 从数据库读取数据后显示成html标签

    也许很多人从数据库中读的数据是不需要数据成html标签的,但是也许有一天你们会发现当我们需要输出成html标签时编译器却自动帮我们输出成字符串了这是我们可以这样来 方法1: 最常用的方法,使用JS或J ...

  2. python操作redis-事务

    #!/usr/bin/python #!coding: utf-8 import redis import sys if __name__=="__main__": try: co ...

  3. MySQL冷备份的跨操作系统还原

    数据来源:linux平台mysql版本为5.7 数据去向:windows平台mysql版本为5.7 操作步骤: 第一步:关闭mysql服务 service mysqld stop 第二步:归档linu ...

  4. SQL Server 影响dbcc checkdb的 8 种因素

    第一种: 数据库的大小. 第二种: IO系统的速度. 第三种: 当前CPU的负荷. 第四种: 当前数据库的并发修改量.因为并发修改量越大维护数据库快照的成本就越高,dbcc 的过程中要创建快照,所以. ...

  5. MYSQL 的 3 类数据类型

    1.数据型: bool,float,double decimal(M,D) M是小数位数(精度)的总数,D是小数点(标度)后面的位数.DECIMAL整数最大位数(M)为65. smallint 小的整 ...

  6. java设计模式--行为型模式--迭代模式

    迭代器模式 概述 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 适用性 .访问一个聚合对象的内容而无需暴露它的内部表示. .支持对聚合对象的多种遍历 ...

  7. grok 正则捕获(就是perl的正则捕获)

    2.3.2 grok 正则捕获: \s+ 和 [\n\t\r\f]+ 一样 1.命名分组格式为(?<grp name>),反向引用时用\k<grp name> 2.命名分组的匹 ...

  8. perl 调用按钮输出到文本框

    sub push_b4 { #$txt -> insert('end'); #select $txt; system("expect c:\\\\expect.txt >expe ...

  9. CDOJ 631 敢说敢做 记忆化搜索and动规

    //跟沈爷学的 传送门http://www.cnblogs.com/Xiper/p/4639636.html #include<cstdio> #include<iostream&g ...

  10. getgrent

    http://baike.baidu.com/link?url=JNyoNvukL-LP7ayYlNNWLv2gPOzn-bjiwuX1CE_QwUTyrRGCWu4NhDW-JznHQoG4aIfw ...