luogu_P1177 【模板】快速排序 (快排和找第k大的数)
【算法】
选取pivot,然后每趟快排用双指针扫描(l,r)区间,交换左指针大于pivot的元素和右指针小于pivot的元素,将区间分成大于pivot和小于pivot的
【注意】
时间复杂度取决于pivot的选取是否能把(l,r)区间分成长度相等的两个子区间。
最优:O(nlogn) 最差:O(n2)
问题解决:
- 版本一:pivot选择区间中间的元素可以解决数组本身就已经排好序的问题,但是无法解决数组中每个元素均相等(第五个点tle)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n,p,i,j;
int a[maxn];
void quick_sort(int l,int r)
{
if(l>r) return;
i = l, j = r;
//swap(a[l], a[(l+r)>>]); ------pivot选区间中间的元素
while(i < j) {//i和j相等时停下来
while(a[j]>=a[l] && i < j) j--; //先右再左很关键!若右指针和左指针相遇则此时左指针指向pivot或小于pivot的元素(前一次有交换),若左指针和右指针相遇,则此时
while(a[i]<=a[l] && i < j) i++; //右指针应当已经寻找到的小于pivot的元素;若先左再右,则反过来了。pivot的位置会出错。
if(i<j) swap(a[i],a[j]);
}
swap(a[l],a[j]);
quick_sort(l,i-);
quick_sort(i+,r);
}
int main()
{
cin>>n;
for(int i = ; i <= n; i++)
cin>>a[i];
quick_sort(,n);
for(int i = ; i <= n; i++)
cout << a[i] << " ";
return ;
}
2、版本二:先判断是否有序,若有序则结束,若无序再按原方法。
3、版本三:每次分成两个子区间,左区间小于等于pivot,右区间大于等于pivot,但不一定确定好pivot的位置,但最终区间长度为2或3的时候必定能确定好
------------------------感觉这种要好写一点,理解了之后,其实都是细节------------------------
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n,p,i,j;
int a[maxn];
void quick_sort(int l,int r)
{
int pivot = a[(l+r)>>];
i = l, j = r;
while(i <= j) { //直到i>j为止,就算数组元素均相等也会向前推进
while(a[i] < pivot) i++;
while(a[j] > pivot) j--;
if(i <= j) {
swap(a[i],a[j]);
i++, j--;
}
}
if(i < r) quick_sort(i,r);
if(j > l) quick_sort(l,j);
}
int main()
{
cin>>n;
for(int i = ; i <= n; i++)
cin>>a[i];
quick_sort(,n);
for(int i = ; i <= n; i++)
cout << a[i] << " ";
return ;
}
4、找第k大的数:分治法类似快排的方法,平均复杂度O(n)【1+2+4+。。。+n/2+n】按版本三的话不太好写,就按版本一来吧:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
int n,k,i,j;
int a[maxn];
int quick_find(int l,int r,int k)
{
int pivot = a[(l+r)>>], rec = ;
i = l, j = r;
swap(a[(l+r)>>], a[l]);
while(i < j) {
while(a[j] >= pivot && i < j) j--, rec++;
while(a[i] <= pivot && i < j) i++;
if(i < j) swap(a[i],a[j]);
}
swap(a[i],a[l]);
if(k == rec + ) return a[i];
else if(k <= rec) return quick_find(i+,r,k);
else return quick_find(l, i-, k-rec-); }
int main()
{
cin>>n>>k;
for(int i = ; i <= n; i++)
cin>>a[i];
cout<<quick_find(,n,k)<<endl;
return ;
}
luogu_P1177 【模板】快速排序 (快排和找第k大的数)的更多相关文章
- 快排法求第k大
快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...
- 找第k大的数
(找第k大的数) 给定一个长度为1,000,000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{ ...
- P1049 找第K大的数
题目描述 给定一个无序正整数序列, 以及另一个数n (1<=n<=1000000), 然后以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3 ...
- 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大
思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...
- 找出N个无序数中第K大的数
使用类似快速排序,执行一次快速排序后,每次只选择一部分继续执行快速排序,直到找到第K个大元素为止,此时这个元素在数组位置后面的元素即所求 时间复杂度: 1.若随机选取枢纽,线性期望时间O(N) 2.若 ...
- 找出整数中第k大的数
一 问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二 举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...
- 基于快速排序思想partition查找第K大的数或者第K小的数。
快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...
- 寻找第K大的数(快速排序的应用)
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数.给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在.测试样例:[1,3,5,2,2],5, ...
- 算法题之找出数组里第K大的数
问题:找出一个数组里面前K个最大数. 解法一(直接解法): 对数组用快速排序,然后直接挑出第k大的数.这种方法的时间复杂度是O(Nlog(N)).N为原数组长度. 这个解法含有很多冗余,因为把整个数组 ...
随机推荐
- nyoj 952 : 最大四边形 (计算几何)
题目链接 任意四边形均可看作是两个三角形拼接得到的(即使是凹四边形),故 可以O(n^2)枚举所有的线段,然后对每条线段O(n)枚举线段端点外的其他点,用来更新以此线段构成的三角形的有向面积的最大值m ...
- 【leetcode】622. Design Circular Queue
题目如下: Design your implementation of the circular queue. The circular queue is a linear data structur ...
- js-点出弹框后(除了点击窗口上的叉子),点其他地方能够关闭窗口???
HTML: <div class="A"> <div class="B"></div> </div> JS: $ ...
- Ubuntu 16.04下使用docker部署MySQL主从复制
(以下docker相关的命令,需要在root用户环境下或通过sudo提升权限来进行操作.) 首先更新 软件源 https://mirrors.tuna.tsinghua.edu.cn/help/ubu ...
- php 客户端调用elasticsearch接口
1.php调用elasticsearch接口[参考资料:https://www.cnblogs.com/php0916/articles/6587340.html] /data/www/syhuo.n ...
- 阿里云安装配置yarn,Nginx
1.和npm 相比yarn 的优势在于 1.比npm快.npm是一个个安装包,yarn 是并行安装. 2.npm 可能会有情况 同样的 package.json 文件在不同的机器上安装的包不一样.导致 ...
- jmeter的日常特殊参数化
1.map转译符号: 如果///Mobile///:///18888888888/// 需要再参数化请这样做,////Mobile////://///${Mobile}///// 2.in ...
- 将MSQL中的数据导出至EXCEL
mysql> show variables like '%secure%';+------------------+---------------------+| Variable_name | ...
- 十九、python内置函数汇总
'''内置函数abs():取绝对值all():每个元素都为真,才是真any():有一个元素为真即为真bin():十进制转二进制hex():十进制转十六进制int():所有的转成十进制oct():十进制 ...
- ps 等程序的选项的三种风格
unix options bsd options gnu long options unix options, which may be grouped and must be preceded by ...