1. ๋ฌธ์ ์ค๋ช
2. ์ ๊ทผ ๋ฐฉ์
quick ์ ๋ ฌ์ ์ด์ฉํด ๋ฌธ์ ๋ฅผ ํ์๋ค. ํ์ง๋ง ๊ธฐ๋ณธ์ ์ธ quick sort๋ก ๋ฌธ์ ๋ฅผ ํ๋ฉด ์๊ฐ์ด๊ณผ๊ฐ ๋๋ค. quick sort์ ์ต์
์๊ฐ๋ณต์ก๋๋ O(n^2) ์ธ๋ฐ, ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ 5,000,000 ์ด๋ผ n^2๋ฅผ ํ๋ฉด 2 ์ต๋ฒ์ ๊ณ์ฐ์ ํ์ฉ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ O(nlogn)์ ๋ค๋ฅธ ์ ๋ ฌ์ ์ฐ๊ฑฐ๋, quick sort๋ฅผ ์ต์ ํ ํด์ค์ผ ํ๋ค.
๋๋ quick sort๋ฅผ ์ต์ ํํ๋ ๋ฐฉํฅ์ ์ ํํ๋ค. ํด๋น ๋ฌธ์ ๋ k๋ฒ์งธ index์ ์๊ฐ ๋ฌด์์ธ์ง๋ง ๊ตฌํ๋ฉด ๋๋ ๋ฌธ์ ์ด๋ฏ๋ก, ๋ชจ๋ ๋ฐฐ์ด์ ์ ๋ ฌ์ํฌ ํ์๊ฐ ์๋ค. ๋ฐ๋ผ์
- ์ด๋ถ ํ์์ฒ๋ผ ๊ตฌ์ญ์ ๋๋ ์, ํ์ ์๋ ๋ถ๋ถ์ ์ ๋ ฌ์ ํ์ง ์๋๋ค.
- K๋ฒ์งธ ์๋ฅผ ์์๋ด๋ฉด ๊ฑฐ๊ธฐ์ ์ข ๋ฃํ๋ค.
โ ํ์ฌ ์ ๋ ฌํ๋ ค๋ ๋ฒ์์ ์ค์๊ฐ์ pivot์ผ๋ก ์ค์ ํ๋ค.
โ mid์ start์ ๊ฐ์ ๋ฐ๊ฟ์ pivot ๊ฐ์ด ๋ฐฐ์ด ๋งจ ์์ผ๋ก ์ฌ ์ ์๋๋ก ํ๋ค. (pivot์ ์ ์ ์์น ์ฐพ๋ ๊ณ์ฐ ์, ํผ์ ์ด ์๊ธฐ ์ํด)
โ ์ด์ start +1 ~ end ๋ฒ์๋ฅผ ์์ง์ฌ ๊ฐ๋ฉด์ pivot ๊ฐ์ด ๋ค์ด๊ฐ ์ ์ ์์น๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค.
์ด๋ i = start + 1, j = end๋ผ๊ณ ํ๊ฒ ๋ค.
(c-1) j๋ถํฐ ์์ง์ธ๋ค. j๊ฐ ๊ฐ๋ฅดํค๋ ์์น์ ๊ฐ์ด pivot๊ฐ๋ณด๋ค ํฌ๋ฉด j--๋ก ์ผ์ชฝ์ผ๋ก ์ด๋ํ๋ค.
(c-2) ๋ค์์ i๋ฅผ ์์ง์ธ๋ค. i๊ฐ ๊ฐ๋ฅดํค๋ ๊ฐ์ด pivot ๊ฐ๋ณด๋ค ์์ผ๋ฉด i++๋ก ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํ๋ค. (ํด๋น ์์ ๋ i๊ฐ ๋ ์ด์ ์์ง์ผ ๊ณณ์ด ์๋ค.)
(c-3) ๋ง์ฝ j๋ i๊ฐ ์์ง์ด๋ ๋์ค, j๊ฐ ๊ฐ๋ฅดํค๋ ๊ฐ์ด pivot ๋ณด๋ค ์์ ๊ฒฝ์ฐ, ํน์ i๊ฐ ๊ฐ๋ฅดํค๋ ๊ฐ์ด pivot๋ณด๋ค ํด ๊ฒฝ์ฐ ๋ฉ์ถฐ ์์ ๊ฒ์ด๋ค. i < j ์ธ ์ํฉ์์ i์ j๊ฐ ๋ฉ์ถฐ์์ ๊ฒฝ์ฐ, ๋ ๊ฐ์ ์์น๋ฅผ ๋ฐ๊พธ๊ณ , i++, j--๋ก ์ด๋ํ๋ค. (pivot ๊ธฐ์ค์ผ๋ก ๊ทธ๋ณด๋ค ํฐ ๊ฐ์ ์ค๋ฅธ์ชฝ์ผ๋ก, ๊ทธ๋ณด๋ค ์์ ๊ฐ์ ์ผ์ชฝ์ผ๋ก ๋ฐ๊ธฐ)
โ arr[start]์ arr[j]์ ๊ฐ์ swap ํ๋ค.์ i๊ฐ ์๋๊ณ j์ธ๊ฐ?
์๋ํ๋ฉด, j์ ๊ฒฝ์ฐ ์ข
๊ตญ์ ์ง์นญํ๋ ๊ฐ์ pivot๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ๊ฐ์ด๋ค. ์๋ํ๋ฉด pivot๋ณด๋ค ํฐ ๊ฐ์ ๋ณด๋ฉด ์ธ์ ๋ ์ผ์ชฝ์ผ๋ก ์๋ฆฌ ์ด๋์ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋์ j์ start์ ๊ฐ์ ์๋ฆฌ ๋ฐ๊ฟ ํด๋, pivot ๊ธฐ์ค ์ ๋ ฌ์ด๋ผ๋ quick-sort์ ์๋ฏธ๋ ๋ฒ์ด๋์ง ์๋๋ค.
โ pivot์ index์ K๋ฅผ ๋น๊ตํ๋ค.
ํ์ฌ pivot๋ง์ ์ ๋ ฌ์ด ๋ ์ํ์ด๋ค.
pivot์ index๋ฅผ P๋ผ๊ณ ํ ๋, P==K์ด๋ฉด K๋ฒ์งธ ์๋ฅผ ์ฐพ์์์ผ๋ก ์ ๋ ฌ์ ์ข
๋ฃํ๊ณ ์ถ๋ ฅํ๋ค.
P < K ์ด๋ฉด pivot์ ์์น ์ค๋ฅธํธ์ K๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ถ๋ถ๋ง ์ ๋ ฌ์ ์ด์ด๊ฐ๋ค.
P > K ์ด๋ฉด pivot์ ์์น ์ผํธ์ K๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ถ๋ถ๋ง ์ ๋ ฌํ๋ค.
์ด๋ ์ฌ๊ท๋ฅผ ์ด์ฉํ๋ค.
3. ์ฝ๋ ๋ถ์
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
// 0. ๊ฐ ์
๋ ฅ
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken()) - 1;
int [] arr = new int [N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
quickSort(arr, 0, N-1, K);
System.out.println(arr[K]);
}
public static void quickSort(int [] arr, int start, int end, int K) {
if(start < end) {
int pivot = partition(arr, start, end);
if(pivot == K) return;
else if (K < pivot) quickSort(arr, start, pivot-1, K);
else quickSort(arr,pivot+1, end, K);
}
}
// partition: ์ ํด์ง ๋ฒ์ ๋ด์ pivot ๊ฐ์ด ๋ค์ด๊ฐ ์์น๋ฅผ ์๋ ค ์ฃผ๋ ํจ์
// pivot ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์ข ์ฐ๋ก ์์ญ์ด ๊ฐ๋ผ์ง.
public static int partition(int[] arr, int start, int end) {
// ๋ง์ฝ ๋ฒ์๊ฐ 1์ด๋ฉด, ๋ ๊ฐ์ ์ ๋ ฌ๋ง ํ๋ฉด ๋จ.
if(start+1==end){
if(arr[start] > arr[end]) swap(arr, start, end);
return end;
}
int mid = (start+end)/2; // pivot์ index
swap(arr,start,mid); // pivot ๊ฐ์ ์ผ์ชฝ ๋์ผ๋ก ๋ฐ์ด์, ๋ฐ์์ ์ด๋ฃจ์ด์ง, pivot์ ์ง์ง ์์น ์ฐพ๊ธฐ ๊ณ์ฐ์ ํท๊ฐ๋ฆฌ์ง ์๊ฒ ๋ง๋ฆ
int pivot = arr[start];
int i = start+1; int j = end;
while (i <= j) { // ์ค์! J๊ฐ ์์ ํ pivot๋ณด๋ค ํฐ ์์ญ์ ๋น ์ ธ ๋์์ผ ํ๋ฏ๋ก, i == j ๋ฅผ ๋์ด์์ ์๋ก ์ด๊ธ๋๋๋ก ํด์ผํ๋ค.
while (j>= start+1 && pivot < arr[j]){ // ์ค๋ฅธ์ชฝ ๊ฐ์ด ๊ธฐ์ค ๊ฐ๋ณด๋ค ํฌ๋ฉด ๋ด๋ฒ๋ ค ๋๊ณ ๋ค์์ผ๋ก ๋์ด๊ฐ
j--;
}
while (i<=end&&pivot>arr[i]) { // ์ผ์ชฝ ๊ฐ์ด ๊ธฐ์ค ๊ฐ๋ณด๋ค ์์ ๊ฒฝ์ฐ, ๊ทธ๋๋ก ๋๊ณ ๋ค์์ผ๋ก ๋์ด๊ฐ๋ค.
i++;
}
if(i <= j){ // ๋ ๋ค ๋ฉ์ถฐ ์๋๋ฐ, ์์ง ์๋ก ์ ๋ง๋ ๊ฒฝ์ฐ, ์ผ์ชฝ ๊ฐ์ ๊ธฐ์ค ๊ฐ๋ณด๋ค ํฌ๊ณ , ์ค๋ฅธ์ชฝ ๊ฐ์ ๊ธฐ์ค ๊ฐ๋ณด๋ค ์์ ๊ฒ์. ๋ฐ๋ผ์ ์๋ก swap
swap(arr,i++,j--);
}
}
arr[start] = arr[j];
arr[j] = pivot;
return j;
}
public static void swap(int [] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
4. ์ฑ์ฅํ๊ธฐ
์ด๋ฐ ์์ผ๋ก ์ ๋ ฌ์ด ํ์ํ ๋ถ๋ถ๋ง ์ ํํด์ ์ ๋ ฌํ๋ ๊ฒ์ quick-selection ์ ๋ ฌ์ด๋ผ๊ณ ํ๋ค.