STL 排序類 解決第k大問題

2021-10-05 07:52:03 字數 4789 閱讀 7537

前言:

相信我們會遇到過在一堆無序的數字中,問你第k大的數字是哪乙個或者第k小的數字。

當然,最簡單的做法就是排序,然後直接輸出第k大的數字,這樣的話時間複雜度約為n^(3/2);

給定乙個長度為n的整數數列,以及乙個整數k,請用快速選擇演算法求出數列的第k小的數是多少。

輸入格式

第一行包含兩個整數 n 和 k。

第二行包含 n 個整數(所有整數均在1~109範圍內),表示整數數列。

輸出格式

輸出乙個整數,表示數列的第k小數。

資料範圍

1≤n≤100000,

1≤k≤n

輸入樣例:

5 32 4 1 5 3

輸出樣例:

3

想必一說這個詞,可能不知道說的是啥,沒關係。我們換個詞語,很熟悉的,叫做——快排法,這個應該大家都知道,就是排序演算法中的一種。

快速選擇演算法與快速排序演算法的區別在於,快速選擇演算法只會對支點的一側進行排序,或者輸出。令|a|為a中的元素個數,查詢a中第k個最小元,演算法步驟如下:

1)如果|a|=1,那麼k=1,則將a中的元素作為答案返回

2)取a中一元素v,稱為樞紐元。

3)將a-分為兩個不相交的集合:a1和a2,其中a1中的元素值小於等於v,a2中的元素值大於等於v

4)若k<=|a1|,那麼第k個最小元必然在a1中,在這種情況下返回quciksort(a1,k).如果k=1+|a1|,那麼樞紐元就是第k個元素,我們將其返回。否則第k個最小元就在|a2|中,它是a2中的第(k-|a1|-1)個最小元,則遞迴呼叫返回quicksort(a2,k-|a1|-1).

**實現:

# include

using

namespace std;

const

int n =

1e5+10;

int a[n]

;int

quick_sort

(int left,

int right,

int k)

} a[left]

= a[i]

; a[i]

= st;

if(k==i)

return a[i]

;else

if(i

else

}int

main

(void

)

分割線
神裝利器:std::nth_element
//custom (1)	

template

<

class

randomaccessiterator

>

void nth_element (randomaccessiterator first, randomaccessiterator nth,

randomaccessiterator last)

;//custom (2)

template

<

class

randomaccessiterator

,class

compare

>

void nth_element (randomaccessiterator first, randomaccessiterator nth,

randomaccessiterator last, compare comp)

;

總的來說,就一句話-----在陣列或容器中將第幾大或小的元素放到該放的位置上。(預設第幾小,可以用cmp自定義為第幾大)

比如:nth_element(q.begin(),q.begin()+5,q.end()); 表示求第六小的數字,因為下標是從0開始,也就是說把第六小的數字放在q[5]這個位置上。

舉個例子:

// nth_element example

#include

// std::cout

#include

// std::nth_element, std::random_shuffle

#include

// std::vector

bool myfunction (

int i,

int j)

int main (

)

再來乙個裝逼神神器-----std::partial_sort

partial_sort 是c++ stl 演算法元件中的其中乙個演算法,其作用是對序列區域性元素進行排序,預設排序是公升序,使序列中的first—middle(不包括middle)以遞增順序排序,置於[first, middle)內。它有兩個過載函式。

//default (1)	

template

<

class

randomaccessiterator

>

void partial_sort (randomaccessiterator first, randomaccessiterator middle,

randomaccessiterator last)

;//custom (2)

template

<

class

randomaccessiterator

,class

compare

>

void partial_sort (randomaccessiterator first, randomaccessiterator middle,

randomaccessiterator last, compare comp)

;

繼續舉個例子
// partial_sort example

還有個這玩意------std::partial_sort_copy,跟前面用法一樣,唯一不同的就是把結果弄到另乙個容器上

//default (1)	

template

<

class

inputiterator

,class

randomaccessiterator

>

randomaccessiterator

partial_sort_copy (inputiterator first,inputiterator last,

randomaccessiterator result_first,

randomaccessiterator result_last)

;//custom (2)

template

<

class

inputiterator

,class

randomaccessiterator

,class

compare

>

randomaccessiterator

partial_sort_copy (inputiterator first,inputiterator last,

randomaccessiterator result_first,

randomaccessiterator result_last, compare comp)

;

第k大問題

利用快排的特點 假設預設公升序排序 每一次快排操作都能確定乙個數在排序結果中的最終固定位置,即該位置 pos 上的數為 n pos 大的數,且之後的數即為前 n pos 大的數,故此方法即可求第k大的數 也可求前k大的數。設取第k大的數,即index k 若 pos index 就繼續快排右側的資料...

快速排序實現與如何求解第K大問題

快速排序,這種排序方式時間複雜度平均情況下為o nlogn 而且適合資料非常多的排序方法。它採用一種分治思想 在執行的過程種就把第k大問題解決了。很簡單但是非常巧妙,不用額外申請記憶體空間。如下可以自己跑一下 package com.jxd.test public class quicksort n...

快速排序 第K大 第K小的問題

這裡的快排 是一種稍微改進的快排,即減少一些不必要的交換次數。quick sort void quick sort int s,int e a s a i 此時 i j 為最後找到的最小的數,需要放在樞軸處 即位置s a i x quick sort s,i 1 quick sort i 1,e 第...