티스토리 뷰
문제
오늘도 서준이는 병합 정렬 수업 조교를 하고 있다. 아빠가 수업한 내용을 학생들이 잘 이해했는지 문제를 통해서 확인해 보자.
N개의 서로 다른 양의 정수가 저장된 배열 A가 있다.
병합 정렬로 배열 A를 오름차순 정렬할 경우 배열 A에 K 번째 저장되는 수를 구해서 우리 서준이를 도와주자.
입력
첫째 줄에 배열 A의 크기 N(5 ≤ N ≤ 500,000), 저장 횟수 K(1 ≤ K ≤ 108)가 주어진다.
다음 줄에 서로 다른 배열 A의 원소 A1, A2,..., AN이 주어진다. (1 ≤ Ai ≤ 109)
출력
배열 A에 K 번째 저장되는 수를 출력한다. 저장 횟수가 K 보다 작으면 -1을 출력한다.
풀이
병합 정렬을 한 번 구현해 보라는 문제이다.
그냥 구현하라고 하면 다른 정렬로 통과할 수도 있으니
특정 횟수에 정렬되는 숫자를 출력해 보라는 의도인 것 같다.
병합 정렬은 이름대로 주어진 배열을 가능한 작게 쪼갠 다음 순서대로 합치며 정렬하는 방식이다.
자료의 상태에 영향을 받지 않는 안정 정렬이라는 장점이 있으나 위 그림에서 보는 것처럼
자료의 크기만 한 메모리 공간이 요구된다는 단점이 있다. 어쨌거나 구현해서 풀어보자.
import java.util.Scanner;
public class Prob24060_2 {
private static int[] temp;
private static int k;
private static int cnt = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
k = sc.nextInt();
int[] arr = new int[a];
temp = new int[a];
for (int i = 0; i < a; i++) {
arr[i] = sc.nextInt();
}
mergeSortImpl(arr, 0, a - 1);
System.out.println(-1);
}
public static void mergeSortImpl(int[] arr, int start, int end) {
if (start == end) return; // 끝까지 쪼개면 리턴
int mid = (start + end) / 2; // 절반으로 나누기
mergeSortImpl(arr, start, mid); // 왼쪽 절반 재귀호출
mergeSortImpl(arr, mid + 1, end); // 오른쪽 절반 재귀호출
mergeSort(arr, start, mid, end);
}
private static void mergeSort(int[] arr, int start, int mid, int end) {
int left = start;
int right = mid + 1;
int idx = left;
while (left <= mid && right <= end) {
if (arr[left] <= arr[right])
temp[idx++] = arr[left++];
else
temp[idx++] = arr[right++];
}
while (left <= mid)
temp[idx++] = arr[left++];
while (right <= end)
temp[idx++] = arr[right++];
left = start;
idx = left;
while (left <= end) {
arr[left++] = temp[idx++];
cnt++;
if (cnt == k) {
System.out.println(arr[left - 1]);
System.exit(0);
}
}
}
}
mergeSortImpl에서 주어진 배열을 쪼갠 후 mergeSort를 통해 합치는 식으로 구현했다.
그 와중에 정렬이 한 번 끝난 숫자가 배열에 입력될 때마다 cnt를 올려주었고 해당 숫자가 주어진 k와 같아지면
숫자를 출력하고 시스템을 종료, 끝까지 가도 찾을 수 없는 경우엔 -1을 출력하도록 해주었다.
재귀를 이용해서 쪼개고 합친다는 개념만 받아들이면 병합정렬 자체는 어려울 게 없어서 크게 설명할 것도 없다.
'Algorithm > [Java+Python+JavaScript]BackJoon' 카테고리의 다른 글
[BackJoon]2798번 (0) | 2023.01.17 |
---|---|
[BackJoon]11729번 (1) | 2023.01.15 |
[BackJoon]2798번 (2) | 2023.01.14 |
[BackJoon]18870번 (4) | 2023.01.02 |
[BackJoon]10814번 (2) | 2023.01.01 |
[BackJoon]11651번 (4) | 2022.12.31 |
- Total
- Today
- Yesterday
- 기술면접
- java
- 알고리즘
- 리스트
- 맛집
- 스프링
- Python
- 여행
- 동적계획법
- 유럽여행
- 스트림
- a6000
- 남미
- 세모
- RX100M5
- 지지
- 유럽
- 칼이사
- 자바
- BOJ
- 야경
- 중남미
- 면접 준비
- Algorithm
- 파이썬
- 세계일주
- 백준
- 세계여행
- spring
- Backjoon
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |