利用快排partition求前N小的元素
求前k小的数,一般人的想法就是先排序,然后再遍历,但是题目只是求前N小,没有必要完全排序,所以可以想到部分排序,而能够部分排序的排序算法我能想到的就是堆排序和快排了。
第一种思路,局部堆排序。
首先,建立一个大小为N的大顶堆,时间复杂度klgk,然后用其余的数和堆顶元素比较,如果小于堆顶元素则与堆顶元素交换,并进行一次调整,时间复杂度(n-k)lgk,然后klgk可以常数级,(n-k)lgk=O(n)。
第二种思路,利用快排的partition。
只需要稍微修改qsort函数即可,增加判断条件,当partition小于k则快排partition+1到right,如果partition大于k则快排left到partition-1,如果partition等于k,则直接输出数组前k个数,即所求。因为每一轮partition,左部的数都会小于基准数,右部大于基准数 ,所以如果基准下标小于k,说明第k大的数肯定不在基准左部,所以可以缩小搜索条件,直接搜索基准右部,同理基准下标大于k,说明第k大的数肯定不在基准右部,直接搜索基准左部。不过需要注意的一点是qsort中的if(left<right)要改成if(left<right),因为判断partition==k要在下一个递归中。时间复杂度网上证明是O(n)。
public class partitionFindN {
@Test
public void test(){
int[] num = {1,5,9,7,3,4,8,1,6,3,5};
findSmallN(num,8);
}
public void findSmallN(int[] num,int n){
Qsort(num,0,num.length-1,n-1);
}
public void Qsort(int[] num,int left,int right,int k){
if(left<=right){
int partition = partition(num,left,right);
if(partition==k){
System.out.println("前"+(k+1)+"小的元素为:");
for(int i =0;i<= k;i++){
System.out.print(num[i]+" ");
}
}
else if(partition<k){
Qsort(num,partition+1,right,k);
}
else{
Qsort(num,left,partition-1,k);
}
}
}
public int partition(int[] num,int left,int right){
int partition = num[left];
while(left<right){
while(left<right && num[right]>=partition){
right--;
}
swap(num,left,right);
while(left<right && num[left]<=partition){
left++;
}
swap(num,left,right);
}
return left;
}
public void swap(int[] num,int m,int n){
int temp = num[m];
num[m] = num[n];
num[n] = temp;
}
}
利用快排partition求前N小的元素的更多相关文章
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- 快排法求第k大
快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...
- 记录一个基于Java的利用快排切分来实现快排TopK问题的代码模板
使用快排切分实现快排和TopK问题的解题模板 import java.util.Arrays; public class TestDemo { public static void main(Stri ...
- 算法导论-顺序统计-快速求第i小的元素
目录 1.问题的引出-求第i个顺序统计量 2.方法一:以期望线性时间做选择 3.方法二(改进):最坏情况线性时间的选择 4.完整测试代码(c++) 5.参考资料 内容 1.问题的引出-求第i个顺序统计 ...
- 求第k小的元素
用快排解决: 用快排,一趟排序后,根据基准值来缩小问题规模.基准值的下角标i 加1 表示了基准值在数组中第几小.如果k<i+1,那就在左半边找:如果k>i+1那就在右半边找.当基准值的下角 ...
- 隐式Dijkstra:在状态集合中用优先队列求前k小
这种技巧是挺久以前接触的了,最近又突然遇到几道新题,于是总结了一下体会. 这种算法适用的前提是,标题所述的"状态集合"大到不可枚举(否则枚举就行了qaq) ...
- 求第 k 小:大元素
#include<bits/stdc++.h> using namespace std; void swap_t(int a[],int i,int j) { int t=a[i]; a[ ...
- [剑指Offer]39-数组中出现次数超过一半的数字(快排延申,找第k大数同理)
题目链接 https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&t ...
- Hints of sd0061(快排思想)
Hints of sd0061 Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- Jenkins持续集成构建自动化测试项目
1.配置内容安全策略(配置一次): 1.1.构建一个自由风格的软件项目 1.2.Build Triggers:Build when job nodes start 1.3.Build:Execute ...
- SpringMvc执行过程
--Test过程: 1. 先执行各种 Filter 2. HttpServlet.service(ServletRequest req, ServletResponse res) 3. HttpSer ...
- kvm虚拟化管理平台WebVirtMgr部署-完整记录(1)
公司机房有一台2U的服务器(64G内存,32核),由于近期新增业务比较多,测试机也要新增,服务器资源十分有限.所以打算在这台2U服务器上部署kvm虚拟化,虚出多台VM出来,以应对新的测试需求.当KVM ...
- SpringCloud设定Feign底层实现
1. 概述 版本: spring-boot: 1.5.9.RELEASE spring-cloud: Dalston.SR5 在默认情况下 spring cloud feign在进行各个子服务之间的 ...
- C. Books Queries
链接 [http://codeforces.com/contest/1066/problem/C] 题意 开始空队列,可以进行前插和后插,还可以查询使某个数的为最左或最右需要去掉的最少数字 分析 模拟 ...
- Week 2 代码审查
我的伙伴是6班的小伙子潘礼鹏,经过几天的相处我觉得真的是说话很有趣的人,性格非常好,我们很划得来. 以下为我对他的代码的审查结果: VS2012与VS2013的兼容性 在这里写一个工具集的问题,不同的 ...
- 《Linux内核分析》第八周
<Linux内核分析>第八周 PART ONE 知识点总结 一.进程切换的关键代码switch_to 1.进程调度与进程调度的时机 (1)进程分类: I/O型(执行块,频繁) CPU型(大 ...
- linux第三次实践:ELF文件格式分析
linux第三次实践:ELF文件格式分析 标签(空格分隔): 20135328陈都 一.概述 1.ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文 ...
- PHP使用echo输出标签设置CSS样式问题
使用php是可以输出HTML标签的,这为页面设计带来很大方便. 在此记录php输出标签设置CSS样式的问题: echo可使用''.""或你不用引号,如果想要输出带CSS样式的HTM ...
- 结对项目junit测试用例
题目:我们假设我们要写一个整数除法的类,并且给他写测试用例. 结对分工:滕娟负责写代码,搜集资料,整理,潘广玫负责进行测试,处理测试结果 github地址链接: https://github.com/ ...