基于快速排序思想partition查找第K大的数或者第K小的数。
快速排序
下面是之前实现过的快速排序的代码。
function quickSort(a,left,right){
if(left==right)return;
let key=partition(a,left,right);//选出key下标
if(left<key){
quickSort(a,left,key-1);//对key的左半部分排序
}
if(key<right){
quickSort(a,key+1,right)//对key的右半部份排序
}
}
function partition(a,left,right){
let key=a[left];//一开始让key为第一个数
while(left<right){//扫描一遍
while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
right--;
}
[a[left],a[right]]=[a[right],a[left]];//交换
while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
left++;
}
[a[left],a[right]]=[a[right],a[left]];//交换
}
return left;//把key现在所在的下标返回
}
明显我们可以看出快排的思想是每次找到一个基准数,将数组排列成基准数左边的每个数都比基准数大,右边的每个数都比基准数小的序列。 通过这个思想,我们可以稍微修改QuickSort函数,使它变成findKmax函数,使之拥有快速查找前k个最大的数。
基于快速排序思想查找第K大的数
function findKmax(a,k){
let left=0,right=a.length-1;
let key=partition(a,left,right);
let len=a.length-key;
while(len!=k){
if(len>k){
key=partition(a,key+1,right);
}else{
key=partition(a,left,key-1);
}
len=a.length-key;
}
return a[key];
}
function partition(a,left,right){
let key=a[left];//一开始让key为第一个数
while(left<right){//扫描一遍
while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
right--;
}
[a[left],a[right]]=[a[right],a[left]];//交换
while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
left++;
}
[a[left],a[right]]=[a[right],a[left]];//交换
}
return left;//把key现在所在的下标返回
}
重点是要注意判定边界条件,left,right,k三个都在变,因此需要检验
同理,还可以求第K小的数
function findKmin(a,k){//查找第K小的数
let left=0,right=a.length-1;
let key=partition(a,left,right);
while(key!=k-1){
if(key>k-1){
key=partition(a,left,key-1);
}else{
key=partition(a,key+1,right);
}
}
return a[key];
}
function partition(a,left,right){
let key=a[left];//一开始让key为第一个数
while(left<right){//扫描一遍
while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较
right--;
}
[a[left],a[right]]=[a[right],a[left]];//交换
while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较
left++;
}
[a[left],a[right]]=[a[right],a[left]];//交换
}
return left;//把key现在所在的下标返回
}
基于快速排序思想partition查找第K大的数或者第K小的数。的更多相关文章
- 主席树入门——询问区间第k大pos2104,询问区间<=k的元素个数hdu4417
poj2104找了个板子..,但是各种IO还可以进行优化 /* 找区间[l,r]第k大的数 */ #include<iostream> #include<cstring> #i ...
- Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)
题目原文 Selection in two sorted arrays. Given two sorted arrays a[] and b[], of sizes n1 and n2, respec ...
- 利用划分树求解整数区间内第K大的值
如何快速求出(在log2n的时间复杂度内)整数区间[x,y]中第k大的值(x<=k<=y)? 其实我刚开始想的是用快排来查找,但是其实这样是不行的,因为会破坏原序列,就算另外一个数组来存储 ...
- 寻找数组中第K大的数
给定一个数组A,要求找到数组A中第K大的数字.对于这个问题,解决方案有不少,此处我只给出三种: 方法1: 对数组A进行排序,然后遍历一遍就可以找到第K大的数字.该方法的时间复杂度为O(N*logN) ...
- POJ 2104 K-th Number (区间第k大)
题意:给定一个序列A,接下来又m个询问,每个询问输出A[L,R]中的第K大.(保证第k大存在) 思路: 我想拿来练习“可持久化线段树”的,搜到这个比较巧的算法也可以解决这个问题,叫“归并树?.大概的思 ...
- 第K大01背包
其实这个问题,真的挺好想的,但是我咋想了那么久呢~~ 很好理解,第K大01背包一定基于01背包,dp数组也很容易的想到由dp[V] ----> dp[V][K],来表示背包容量是V时候的第 ...
- POJ 2104 K-th Number 主席树(区间第k大)
题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...
- Count on a tree(SPOJ COT + 树上第k大 + 主席树 + LCA)
题目链接:https://www.spoj.com/problems/COT/en/ 题目: 题意: 给你一棵有n个节点的树,求节点u到节点v这条链上的第k大. 思路: 我们首先用dfs进行建题目给的 ...
- 行列有序矩阵求第k大元素
问题来源:http://www.careercup.com/question?id=6335704 问题描述: Given a N*N Matrix. All rows are sorted, and ...
随机推荐
- Linux基础(二)centOS7密码重置
之前安装linux的时候,为了安全起见,起了一个非常特别的,长的密码.然后,就不记得了密码. 下面通过进入单用户模式,就行挽救. 1>重启系统,在系统菜单选择页按 [上下方向键],使界面停在该界 ...
- sqli-labs(十六)(order by注入)
第四十六关: http://www.bubuko.com/infodetail-2481914.html 这有篇文章讲得还不错可以看下 这关是order by后面的一个注入,用报错注入和盲注都是可以的 ...
- filename
package com.enjoyor.soa.traffic.server.tms.controller; import java.io.BufferedReader;import java.io. ...
- 等比数列二分求和(logn复杂度)
看完这个之后,感觉数学简直太厉害了 转载自:http://blog.csdn.net/acdreamers/article/details/7851144 今天我们学习如何有效地求表达式的值.对于这个 ...
- 第零章 HTML启蒙知识与网站开发流程
Web前端启蒙知识:1.软件架构模式a)B/S架构:Browser-Server 浏览器服务器模型b)C/S架构:Client-Server 客户端服务器模型注1:浏览器是运行网页的应用程序注2:B/ ...
- Delegate,Action,Func,匿名方法,匿名委托,事件
一.委托Delegate 一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本的数据类型(或者没有参数),比如 public void HelloWorld ...
- sql 查询重复数据,删除重复数据,过滤重复数据
select * from (SELECT titleid,count(titleid) c FROM [DragonGuoShi].[dbo].[ArticleInfo] group by titl ...
- Unity shader学习之轮廓效果
将物体描一层边可以使游戏看起来具有卡通风格,一种简单的实现方法如下: 将物体渲染2次,即使用2个通道. 第一个通道将顶点沿法线(或中心点到顶点的方向)做一个偏移,即将模型扩大一点,并将颜色渲染成轮廓的 ...
- [4]传奇3服务器源码分析一 SelGate
1. 2 留存 服务端下载地址: 点击这里
- websocket发送接收协议
一.websocket接收数据 1)固定字节(1000 0001或1000 0010); ---区分是否是数据包的一个固定字节(占1个字节) 个字节是数据的长度; 3)mark 掩码为包长之后的 ...