当需要在无需列表中寻找第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. SQL Server 解决CPU 高占用的一般step

    第一步: 看这些CPU是不是SQL Server用的. 第二步: 确定SQL Server 有没有引发17883\17884错误 第三步: 找出使用CPU最高的语句进行优化.(sys.dm_exec_ ...

  2. URL,URLConnection,HttPURLConnection的使用

    URLConnection与HttPURLConnection都是抽象类,无法直接实例化对象.其对象主要通过URL的openconnection方法获得. 值得注意的是:1.openConnectio ...

  3. thinkphp中的_get,_post,_request

    ThinkPHP没有改变原生的PHP系统变量获取方式,所以依然可以通过$_GET. $_POST.$_SERVER.$_REQUEST 等方式 来获取系统变量,不过系统的Action类提供了对系统变量 ...

  4. 全选demo

    我们处理数据时,最好能够支持全选操作. 选中之后,进行删除,或其他处理. 我自己写了一个demo. 主要功能: 1.点击全部选中 2.点击全部取消 3.然后进行获取选中的id,进行处理 代码如下: & ...

  5. iscroll5 版本下的 上拉,下拉 加载数据

    上拉时候只是加载第一页的内容,可根据实际情况修改其中的代码. <section id="downwraper" class="nodeBottom bot0 bgf ...

  6. chrome console 调试xpath

    chrome console F12->$x(“//title”) [<title>Online Tools for Software Developers (Free)</t ...

  7. Linux开发环境配置

      配置JDK: tar -xzvf jdk-7u71-linux-x64.tar.gz rm -f jdk-7u71-linux-x64.tar.gz 测试:java -version 配置Grad ...

  8. magent编译安装及常见错误

    安装magent到/usr/local/下 cd /usr/local mkdir magent cd magent/ wget http://memagent.googlecode.com/file ...

  9. Hibernate征途(一)之初识

    相见恨晚 很久以前,大概从开始接触数据库开始,就闪过这样一个想法,怎么看怎么觉得数据库表和vb的类模块很像,不是么?除了vb类模块还有函数外:越往下学觉得二者越像,尤其在三层时学到实体类的概念,我去, ...

  10. 基于zepto的手机焦点图touchstart touchmove

    基于zepto的手机焦点图,查看地址:demo (建议使用手机浏览器查看)代码如下: <!DOCTYPE HTML> <html> <head> <title ...