문제
백준이는 동생에게 "가운데를 말해요" 게임을 가르쳐주고 있다. 백준이가 정수를 하나씩 외칠때마다 동생은 지금까지 백준이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 백준이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.
예를 들어 백준이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. 백준이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
0.1 초 | 128 MB | 52243 | 15230 | 11428 | 30.303% |
입력
첫째 줄에는 백준이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 백준이가 외치는 정수가 차례대로 주어진다. 정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.
출력
한 줄에 하나씩 N줄에 걸쳐 백준이의 동생이 말해야 하는 수를 순서대로 출력한다.
예제 입력 1
7
1
5
2
10
-99
7
5
예제 출력 1
1
1
2
2
2
2
5
코드
import java.io.*;
import java.util.*;
class Solution {
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
int n = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
PriorityQueue<Integer> left = new PriorityQueue<>(); //오름차순
PriorityQueue<Integer> right = new PriorityQueue<>(Collections.reverseOrder()); //내림차순
for(int i = 0 ; i < n; i++){
int num = Integer.parseInt(br.readLine());
if(left.size() == right.size()) {
right.offer(num);
}else {
left.offer(num);
}
if(!left.isEmpty() && !right.isEmpty()) { //둘 다 값이 존재하면
if(left.peek() < right.peek()){ // 만약 오른쪽 힙의 제일 큰 값이 왼쪽 힙의 제일 작은 값보다 작으면 교체
int tmp = left.poll();
left.offer(right.poll());
right.offer(tmp);
}
}
sb.append(right.peek() + "\n");
}
System.out.println(sb);
}
}
문제 하단에 있는 알고리즘 분류에 나와 있듯이 우선순위큐를 이용한 문제이다. 코드에서는 왼쪽 큐와 오른쪽 큐를 구분지어 값을 넣는데, 그 이유는 무엇일까?
인덱스가 없는 큐의 특징을 보완하기 위해서이다.
값이 오름차순으로 들어오는 것이 아니기 때문에 입력값들이 정렬된 상태를 유지할 수 있는 자료구조가 필요하다. ArrayList나 Array를 사용하는 것은 값을 조회하는데 빠를 수 있지만, 값이 들어올 때마다 새로 정렬을 수행하는 점은 비효율적이다.
값이 순차적으로 입력될 때 각 큐의 상태는 다음과 같다.
7
1
[] , [1]
5
[5] , [1]
2
[5] , [2, 1]
10
[5, 10] , [2, 1]
-99
[5, 10] , [2, 1, -99]
7
[5, 10, 7] , [2, 1, -99]
5
[5, 10, 7] , [5, 2, -99, 1]
'알고리즘(코딩테스트)' 카테고리의 다른 글
백준 5073번 삼각형과 세 변(JAVA) (2) | 2024.02.28 |
---|---|
백준 23971번 ZOAC 4(JAVA) (1) | 2024.02.27 |
백준 1912번 연속합(JAVA) (0) | 2022.03.02 |
백준 2294번 동전 2(JAVA) (0) | 2022.03.02 |
백준 15683번 감시(JAVA) (0) | 2022.03.02 |
댓글