題目描述
給你乙個長度為n的序列,求序列中第k小數的多少。
輸入描述:
多組輸入,第一行讀入乙個整數t表示有t組資料。
每組資料佔兩行,第一行為兩個整數n,k,表示數列長度和k。
第二行為n個用空格隔開的整數。
輸出描述:
對於每組資料,輸出它的第k小數是多少。
每組資料之間用空格隔開
示例1輸入複製2
5 21 4 2 3 4
3 33 2 1
輸出複製23
分析stl中的nth_element 函式可以過
下面學習一下nth_element的用法
該函式就是找第n小的數的位置,但是沒有返回值。小於等於n_th的數放在前面,大於等於n_th的數放在後面,但是[begin,nth)和(nth,end)這兩個區間並不保證有序。
用法:中間放的是nth
測試**nth_element
(v.begin()
,v.begin()
+nth,v.
end(
))
測試一下#include
using
namespace std;
set<
int> s;
const
int maxn=
5e6;
int t,n,k;
int a[maxn]
;int
read()
while
(c>=
'0'&&c<=
'9')
return f*k;
}int
main()
nth_element
(a,a+k,a+n)
; cout<<
"nth_element之後:"
<
for(
int i=
0;i) cout<
<<
" ";
cout<
printf
("第%d小的數是:%d"
,k,a[k]);
return0;
}
發現:只有n_th是有序的,前半部分無序,後半部分無序。
ac**
下面給一種快排的思路#include
using
namespace std;
set<
int> s;
const
int maxn=
5e6;
int t,n,k;
int a[maxn]
;int
read()
while
(c>=
'0'&&c<=
'9')
return f*k;
}int
main()
nth_element
(a+1
,a+k,a+n+1)
; cout<
<
}return0;
}
複習一下快排的基本思想
step1:選擇分界點 一般 x=q[(l+r)/2]
step2: 使得左半邊區間的數小於等於 x,右半邊區間的數大於等於x
方法是使用頭尾指標,指標的邊界是兩者相遇
step3:遞迴快排左右兩個區間
這裡需要借鑑快排的思想
找第k小的數
step1:選擇分界點:x
step2:記左半邊區間小於等於k 的個數為s1,右半邊區間小於等於k的個數為k-s1
如果k≤s1,說明第k小的數一定在左半邊,只需要遞迴左半邊區間即可
如果k>s1,說明第k小的數一定在右半邊,此時需要遞迴右半邊的區間。
ac**(不含重複的數字)
#include#includeusing namespace std;
const int maxn=1e5+10;
int n,k,a[maxn];
int quick_sort(int l ,int r, int k)
int sl=j-l+1;
if(k<=sl) return quick_sort(l,j,k);
else return quick_sort(j+1,r,k-sl);
}int main()
第k小的數
輸入n個整數和乙個正整數k 1 k n 輸出這些整數從小到大排序後的第k個 思路1 最容易想到的方法 先對這個序列從小到大排序,然後輸出前面的最小的k個數即可。如果選擇快速排序法來進行排序,則時間複雜度 o n logn class solution 時間複雜度o nlogn 思路2 在思路1的基礎...
第k小的數
time limit 5000 ms memory limit 65536 kib problem description 現有乙個包含n個整數 1 n 10000000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k小數並輸出。input 多組輸入。...
第k小的數
time limit 5000 ms memory limit 65536 kib submit statistic problem description 現有乙個包含n個整數 1 n 10000000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k...