前言:
相信我們會遇到過在一堆無序的數字中,問你第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 第...