查询无序列表中第K小元素
当需要在无需列表中寻找第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小元素的更多相关文章
- ch1_5_2求无序序列中第k小的元素
import java.util.Arrays; import java.util.PriorityQueue; public class ch1_5_2求无序序列中第k小的元素 { public s ...
- 有序矩阵中第k小元素
有序矩阵中第k小元素 题目: 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素. 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素. 看到有序就会想 ...
- dfs 二叉树中序遍历迭代解法——求解BST中第k小元素
BST中第K小的元素 中文English 给一棵二叉搜索树,写一个 KthSmallest 函数来找到其中第 K 小的元素. Example 样例 1: 输入:{1,#,2},2 输出:2 解释: 1 ...
- 找出数组[1...n]中第k小元素
//问题描述: 试编写一个算法,使之能够在数组L[1...n]中找出第k小的元素(即从小到大排序后处于第k个位置的元素) #include <stdio.h> // 结合快排思想,查找第5 ...
- 快速排序-无序数组K小元素
13:07:382020-03-10 11:16:13 问题描述: 找到一个无序数组中第K小的数 样例 1: 输入: [3, 4, 1, 2, 5], k = 3 输出: 3 样例 2: 输入: [1 ...
- 【Leetcode 堆、快速选择、Top-K问题 BFPRT】有序矩阵中第K小的元素(378)
题目 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素. 请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ [ 1, 5, 9], [ ...
- [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 ...
- [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 ...
- Leetcode 378.有序矩阵中第k小的元素
有序矩阵中第k小的元素 给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素.请注意,它是排序后的第k小元素,而不是第k个元素. 示例: matrix = [ [ 1, ...
随机推荐
- UVA 120 Stacks of Flapjacks
每次从最底部开始处理,如果不是最大值,则把最大值翻到底部.这就是最优解.原理自己模拟一下就好... 注意半径不是从1开始.数据处理要仔细. #include <iostream> #inc ...
- Oracle EBS-SQL (OM-2):检查OM常用表
--多语言视图 ALTER SESSION SET NLS_LANGUAGE=AMERICAN ; --组织化视图 BEGIN FND_CLIENT_INFO.set_org_context(218) ...
- 切图教程,APP切图实例
- 二探ListView
使用draw9patch 打开内置terminal 输入CD C:\Users\Gaby\AppData\Local\Android\sdk 在该目录下输入draw9patch 导入图片,开始绘制 本 ...
- #include <boost/thread.hpp>
在这个库最重要的一个类就是boost::thread,它是在boost/thread.hpp里定义的,用来创建一个新线程.它已经被纳入C++标准库中. 小结:新一代C++标准将线程库引入后,将简化多线 ...
- C#接口的使用【转】
我们定义一个接口public interface IBark{ void Bark();}再定义一个类,继承于IBark,并且必需实现其中的Bark()方法public class Dog:IBa ...
- 设计师Yoyo:为用户设计产品,让他们生活更美好
Yoyo设计走过的路:纽约爱立信,西雅图美国在线,硅谷雅虎,ATT,深圳腾讯,华为:Yoyo不仅是顶级的交互体验设计师,还是很Open的知识分享者,从职业选择,以及对年轻人的建议几个角度,摘录他的文章 ...
- Gartner公布了集成系统的魔力象限 - Nutanix的关键技术是什么?
读报告,分析报告,写报告.这活儿我不专业.专业的是西瓜哥的这个:http://www.dostor.com/article/2014-06-25/9776476.shtml 再列出个几篇文章供參考: ...
- CentOS 安装nload(流量统计)
yum install gcc gcc-c++ ncurses-devel wget http://www.roland-riegel.de/nload/nload-0.7.2.tar.gz tar ...
- 【并查集+拓扑排序】【HDU1811】【Rank of Tetris】
题意:给你3种关系 A=B,A>B,A<B 问是否排名方式唯一,或者存在矛盾 解 1.读入数据先处理 =号 用并查集的祖先作为代表元素,其他儿子节点都等于跟这个点重叠. 再读入 '< ...