2.4 选择第k大的元素 selection
1.目标:找到N个元素中,第k大的数。
例如:max是k=N--1;min是k=0;median是k=N/2
2.Quick-select 借鉴了快速排序的思想
(1)利用partition保证:
①a[j] is in place
②左边的元素不大于a[j],右边的元素不小于a[j]
(2)在其中一个子数组中重复划分,当j=k时结束
3.实现
package com.cx.sort; public class QuickSelect {
public static Comparable select(Comparable[] a,int k) {
//打乱数组,避免出现最坏情况,平方时间
Shuffling.sort(a);
int lo=0,hi=a.length-1;
while(hi>lo) {
//j in place
int j=partition(a, lo, hi);
//如果j<k,只需要重新划分右边的数组
if(j<k) lo=j+1;
//如果j>k,只需要重新划分左边的数组
else if(j>k) hi=j-1;
else return a[k];
}
return a[k];
} //划分,使得j左边的数不大于a[j],j右边的数不小于a[j]
private static int partition(Comparable[] a,int lo,int hi) {
int i=lo,j=hi+1;
//1.repeat
while(true) {
//1)循环i,直到大于a[lo]
while(less(a[++i], a[lo]))
//不可少,防止出现dcba时,i越界
if(i==hi) break;
//2)循环j,直到小于a[lo]
while(less(a[lo], a[--j]))
if(j==lo) break;
//3)判断是否交叉
if(i>=j) break;
exch(a, i, j);
}
//2.交叉后,交换lo,j
exch(a, lo , j);
//j in place
return j;
} private static boolean less(Comparable v,Comparable w) {
return v.compareTo(w)<0;
} private static void exch(Comparable[] a,int i ,int j ) {
Comparable t=a[i];
a[i]=a[j];
a[j]=t;
}
private static void show(Comparable[] a) {
for(int i=0;i<a.length;i++) {
System.out.print(a[i]+" "); }
System.out.println();
}
public static void main(String[] args) {
String a[]= {"s","o","r","t","e","x","a","m","p","l","e"};
show(a);
//第几大的数(k=0..N-1)
int k=3;
System.out.println("第"+k+"大的数是:"+select(a, k)); }
}
package com.cx.sort; public class Shuffling {
public static void sort(Comparable[] a) {
int N=a.length;
for(int i=1;i<N;i++) {
//第i次迭代,随机找r,r是0-r的随机数
int r=(int)(Math.random()*(i+1));
exch(a, i, r);
}
} private static boolean less(Comparable v,Comparable w) {
return v.compareTo(w)<0;
} private static void exch(Comparable[] a,int i ,int j ) {
Comparable t=a[i];
a[i]=a[j];
a[j]=t;
}
private static void show(Comparable[] a) {
for(int i=0;i<a.length;i++) {
System.out.print(a[i]+" "); }
System.out.println();
}
public static void main(String[] args) {
String a[]= {"s","o","r","t","e","x","a","m","p","l","e"};
show(a);
sort(a);
show(a);
}
}
4.说明:
(1)quick-select:平均花费线性时间,最差的情况是~1/2N2
最差的情况发生在正序或倒序的时候,但是第一步的shuffling可以有效的避免这种情况。
线性时间可以简单的N+1/2N+1/4N+..=~2N
(2)常系数还是相对大了,还需要继续改进算法。
2.4 选择第k大的元素 selection的更多相关文章
- 寻找数组中的第K大的元素,多种解法以及分析
遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...
- LeetCode703 流中第k大的元素
前言: 我们已经介绍了二叉搜索树的相关特性,以及如何在二叉搜索树中实现一些基本操作,比如搜索.插入和删除.熟悉了这些基本概念之后,相信你已经能够成功运用它们来解决二叉搜索树问题. 二叉搜索树的有优点是 ...
- [LeetCode] Kth Largest Element in a Stream 数据流中的第K大的元素
Design a class to find the kth largest element in a stream. Note that it is the kth largest element ...
- 输出数组第k大的元素
用快速排序的思想输出数组第k大的元素: #include<iostream> #include<algorithm> using namespace std; //递归实现:返 ...
- 获取一个数组里面第K大的元素
如何在O(n)内获取一个数组比如{9, 1, 2, 8, 7, 3, 6, 4, 3, 5, 0, 9, 19, 39, 25, 34, 17, 24, 23, 34, 20}里面第K大的元素呢? 我 ...
- POJ 2985 Treap平衡树(求第k大的元素)
这题也能够用树状数组做,并且树状数组姿势更加优美.代码更加少,只是这个Treap树就是求第K大元素的专家--所以速度比較快. 这个也是从那本红书上拿的模板--自己找了资料百度了好久,才理解这个Trea ...
- 力扣:丑数II和数组中前K大的元素
数组中的第K个元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k ...
- [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- 215. Kth Largest Element in an Array【Medium】【找到第 k 大的元素】
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
随机推荐
- Palindromic Subsets 数学 + 线段树
https://www.hackerrank.com/contests/101hack44/challenges/palindromic-subsets 如果有3个a.2个b.1个c. 每个a看成不同 ...
- suricata.yaml (一款高性能的网络IDS、IPS和网络安全监控引擎)默认配置文件(图文详解)
不多说,直接上干货! 前期博客 基于CentOS6.5下Suricata(一款高性能的网络IDS.IPS和网络安全监控引擎)的搭建(图文详解)(博主推荐) 或者 基于Ubuntu14.04下Suric ...
- hihocoder offer收割编程练习赛11 D 排队接水
思路: 莫队算法+树状数组. 莫队算法的基本思想是对大量要查询的区间进行离线处理,按照一定的顺序计算,来降低复杂度.概括来说,我们在知道了[l, r]的解,并且可以通过一个较低的复杂度推出[l - 1 ...
- File文件存储
文件存储的核心是Context提供了一个openFileOutput()与openFileInput()俩个方法 课程demo public class MainActivity extends Ap ...
- 使用RecyclerView
tags: 新建,模板,小书匠 RecyclerView 是 Android 团队新推出的控件,不仅能轻松实现 ListView 的同样的效果,还优化了 ListView 中许多不足之处. 目前 An ...
- (转) 淘淘商城系列——使用FastDFS-Client客户端进行上传图片的测试
http://blog.csdn.net/yerenyuan_pku/article/details/72804018 不久之前,我们实现了商品的类目选择这个功能,但这只是万里长征的第一步,我们还有很 ...
- uiviewcontroller顶级布局控制
@available(iOS 7.0, *) open var edgesForExtendedLayout: UIRectEdge // Defaults to UIRectEdgeAll @ava ...
- CE工具里自带的学习工具--第三关
图解: 重复第5,6,7,8,9步,最终得到:
- github 添加完sshkey之后仍然需要输入密码
1.在家目录下创建.netrc文件,内容如下 machine github.com login username password password window下创建:在用户文件夹如C:\Users ...
- vue列表排序实现中的this问题
最近在看vue框架的知识,然后其中有个例子中的this的写法让我很疑惑 <!DOCTYPE html> <html> <head> <meta charset ...