首页 > 其他分享 >快速选择

快速选择

时间:2023-10-06 11:37:07浏览次数:27  
标签:数列 int 整数 选择 区间 排序 快速

一、算法描述

在我们求一组元素的第\(K\)大值或者前\(K\)大值时,可能最先想到的是对元素进行排序,然后选择第\(K\)大的或者前\(K\)大的值。

不过我们只是想取第\(K\)大的数,有必要将整组元素进行排序吗?当然不必,这就是我们将要介绍的快速选择算法,其时间复杂度可以达到O(n)

思路如下:

  1. 选择分界点,int x = q[l], q[r], q[(l + r) >> 1]
  2. 调整区间,使得左区间所有的数都≤x,使得右区间所有的数都≥x
  3. 判断第k个数在左区间还是右区间,然后递归排序一个区间即可
  • 显然快速选择算法是基于快排的。
  • 最后一步只需要选择一个区间,也就是为什么时间复杂度是O(n)的原因。

二、题目描述

给定一个长度为 \(n\) 的整数数列,以及一个整数 \(k\),请用快速选择算法求出数列从小到大排序后的第 \(k\) 个数。

输入格式

第一行包含两个整数 \(n\) 和 \(k\)。

第二行包含 \(n\) 个整数(所有整数均在 \(1\)~\(10^9\) 范围内),表示整数数列。

输出格式

输出一个整数,表示数列的第 \(k\) 小数。

数据范围

\(1≤n≤100000\)

\(1≤k≤n\)

输入样例:

5 3
2 4 1 5 3 

输出样例:

3 

三、原题链接

AcWing786.第k个数

四、源代码

#include <iostream>

using namespace std;

const int N = 100010;

int n, k;
int a[N];

int quick_sort(int a[], int l, int r, int k)
{
    if (l >= r) return a[l];
    
    int x = a[(l + r) >> 1], i = l - 1, j = r + 1;
    while (i < j)
    {
        do ++i; while (a[i] < x);
        do --j; while (a[j] > x);
        
        if (i < j)  swap(a[i], a[j]);
    }
    
    int sl = j - l + 1;
    if (k > sl) return quick_sort(a, j + 1, r, k - sl);
    else    return quick_sort(a, l, j, k);
}

int main()
{
    cin >> n >> k;
    
    for (int i = 0; i < n; ++i) cin >> a[i];
    
    cout << quick_sort(a, 0, n - 1, k) << endl;
    
    return 0;
}

标签:数列,int,整数,选择,区间,排序,快速
From: https://www.cnblogs.com/grave-master/p/17744347.html

相关文章

  • CSS 基础 5 - CSS 选择器
    基础#id{}ID选择器.class{}类选择器tag{}标签选择器,tag可以是h1,p,div,span,img,nav,footer...*{}通用选择器,选择所有元素,可以和其他复杂选择器组合<divclass="class1class2"id="my-id"></div>注:每个元素可以有多个类,例如上面的HTML,在CSS中......
  • 快速排序
    快速排序使用java实现快速排序publicstaticvoidquickSort(int[]arr,intl,intr){if(l>=r){return;}intlift=l;intright=r;//选取比较的值,取需要排序的序列的第一个数作为基值intp=ar......
  • 快速排序
    一、算法描述快速排序算法是对冒泡排序算法的一种改进算法,在当前所有内部排序算法中,快速排序算法被认为是最好的排序算法之一。快速排序的基本思想:通过一趟排序将待排序的序列分割为左右两个子序列,左边的子序列中所有数据都比右边子序列中的数据小,然后对左右两个子序列继续进行......
  • AcWing_1_1_785_快速排序
    一、题目描述给定你一个长度为n的整数数列。请你使用快速排序对这个数列按照从小到大进行排序。并将排好序的数列按顺序输出。输入格式输入共两行,第一行包含整数n。第二行包含n个整数(所有整数均在\(1∼10^9\)范围内),表示整个数列。输出格式输出共一行,包含n个整数,......
  • 根据某个关键字的指定顺序,重新对数据源快速排序!
    1职场实例小伙伴们大家好,今天我们来继续重温并学习一个Excel使用过程中最基础的技巧之一:如何根据某个关键字指定的顺序,重新对数据源快速排序?这个问题算是判断掌握Excel是否熟练的一个重要指标了,下面我们就来看一下具体的问题场景。如下图所示:A1:B6单元格区域为数据源区域,为一份水果......
  • 选择华为Mate 60 Pro还是iPhone 15?
    根据提供的信息,我将对比华为Mate60Pro和iPhone15的一些关键参数进行总结,帮助你做出选择。品牌和操作系统:-华为Mate60Pro搭载了华为自家的操作系统HarmonyOS4.0。-iPhone15运行苹果的操作系统iOS17。2.CPU和性能:-Mate60Pro采用了华为自家的麒麟9000S六核中央处理器。-......
  • 【基础算法】排序算法 —— 选择排序
    一、算法原理选择排序将数组分为已排序区间和未排序区间,每次选择未排序区间的最小元素,将它放到已排序区间末尾。一次选择会让一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序。 示例:使用选择排序对数组arr=[4,5,6,3,2,1]从小到大排序。第1次选择:第2次选择:......
  • Centos 快速查看占用资源最多的进程
    1、查看占用内存最多的十个进程psaux|head-1;psaux|grep-vPID|sort-rn-k+4|head 2、查看占用cpu最多的十个进程psaux|head-1;psaux|grep-vPID|sort-rn-k+3|head ————————————————版权声明:本文为CSDN博主「zhangjunli」的原创文......
  • MySQL学习(3)B+树索引是如何快速查询的
    前言我们已经知道在磁盘中,有很多索引页,这些页并非在物理结构上相连接,而是通过双向链表关联。如果要查找一条数据,需要通过页目录中的槽,通过二分法定位到分组再进行遍历查找。比如下面这样:SELECT[查询列表]FROM表名WHERE条件; 假设表中只有一个页,在查找记录时,可以根据搜......
  • 02 快速排序(快排)
    #include"stdio.h"voidQuickSort(int*array,intlow,intheight){inti,j,tmp;//两个哨兵,和开头的元素下标inttemp;i=low;j=height;tmp=array[low];if(i>j)//如果下标i大于下标j,函数结束运行{return;}......