【算法】

  选取pivot,然后每趟快排用双指针扫描(l,r)区间,交换左指针大于pivot的元素和右指针小于pivot的元素,将区间分成大于pivot和小于pivot的

【注意】

  时间复杂度取决于pivot的选取是否能把(l,r)区间分成长度相等的两个子区间。

  最优:O(nlogn)  最差:O(n2)

  问题解决:

  1. 版本一: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大的数)的更多相关文章

  1. 快排法求第k大

    快排法求第k大,复杂度为O(n) import com.sun.media.sound.SoftTuning; import java.util.Arrays; import java.util.Ra ...

  2. 找第k大的数

    (找第k大的数) 给定一个长度为1,000,000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{ ...

  3. P1049 找第K大的数

    题目描述 给定一个无序正整数序列, 以及另一个数n (1<=n<=1000000), 然后以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3 ...

  4. 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大

    思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...

  5. 找出N个无序数中第K大的数

    使用类似快速排序,执行一次快速排序后,每次只选择一部分继续执行快速排序,直到找到第K个大元素为止,此时这个元素在数组位置后面的元素即所求 时间复杂度: 1.若随机选取枢纽,线性期望时间O(N) 2.若 ...

  6. 找出整数中第k大的数

    一  问题描述: 找出 m 个整数中第 k(0<k<m+1)大的整数. 二  举例: 假设有 12 个整数:data[1, 4, -1, -4, 9, 8, 0, 3, -8, 11, 2 ...

  7. 基于快速排序思想partition查找第K大的数或者第K小的数。

    快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...

  8. 寻找第K大的数(快速排序的应用)

    有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数.给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在.测试样例:[1,3,5,2,2],5, ...

  9. 算法题之找出数组里第K大的数

    问题:找出一个数组里面前K个最大数. 解法一(直接解法): 对数组用快速排序,然后直接挑出第k大的数.这种方法的时间复杂度是O(Nlog(N)).N为原数组长度. 这个解法含有很多冗余,因为把整个数组 ...

随机推荐

  1. C++ GUI Qt4学习笔记09

    C++ GUI Qt4学习笔记09   qtc++ 本章介绍Qt中的拖放 拖放是一个应用程序内或者多个应用程序之间传递信息的一种直观的现代操作方式.除了剪贴板提供支持外,通常它还提供数据移动和复制的功 ...

  2. 【leetcode】838. Push Dominoes

    题目如下: 解题思路:本题题目中有一点要求很关键,“we will consider that a falling domino expends no additional force to a fa ...

  3. favicon.ico是什么?

    一.什么是favicon? 所谓favicon,便是其可以让浏览器的收藏夹中除显示相应的标题外,还以图标的方式区别不同的网站.favicon 中文名称:网页图标  英文名称:favorites ico ...

  4. STM32内部硬核的认识

    STM32内部含有硬核,对于一些协议(例如:UART,SPI,IIC,CRC等)我们只要调用硬核就可以了,同时我们也可以自己写通信协议. 这些硬核最终肯定是要有引脚输出的,这就是为什么STM32的引脚 ...

  5. POJ 1743 Musical Theme ( 后缀数组 && 最长不重叠相似子串 )

    题意 : 给 n 个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 分析 :  根据题目对于 “ 相似 ” 串的定义,我们可以将原 ...

  6. Apache主要配置文件http.conf

    1.基本概念 Define SRVROOT "/Apache24" ServerRoot "${SRVROOT}" #Apache安装的根路径 #Listen ...

  7. Python_015(面向对象(接口类,抽象类,多态,封装)

    一.抽象类与接口类 1.抽象类:抽象即类似或者说比较像的部分,继承描述的是父类与子类的一种关系,要找出这种关系,必须先抽象再继承; a:抽象分成两个层次: 1)由对象->类:将两个有相似地方的对 ...

  8. ios8来了,屏幕更大,准备好使用 iOS Auto Layout了吗?

    引言: Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 要完全掌握Au ...

  9. java配置环境变量 jdk1.8

    1.首先第一步安装JDK window系统安装java 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:http://www.oracle.com/technetwork/java/j ...

  10. Flashtext:大规模数据清洗的利器

    Flashtext:大规模数据清洗的利器 在这篇文章中,我们将介绍一种新的关键字搜索和替换的算法:Flashtext 算法.Flashtext 算法是一个高效的字符搜索和替换算法.该算法的时间复杂度不 ...