지금까지 값중 “중간값”
“지금까지” 라는게 문제임
1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야
N의 개수는 10만개 이하.
일단 브루트 포스로 생각해보면
백준이가 수를 부를 때 마다(n번= 10만번 ), 정렬하고(nlogn), ⇒n^2logn , 중앙값찾기( size상 중간 값 or 를 한다면? → O(n^2logN) → 안됨
제한시간이 0.1 초 → 무조건.. 기존의 데이터를 사용해야하는 문제인듯하다.
규칙 을 찾고자 하였으나, 어차피 정렬을 해야만 했다.
감이 오지 않았다.
다른 사람들의 풀이를 봤는데 , 어떻게 저걸 생각한걸까
두 개의 우선순위 큐를 사용한다. 이 때 아래의 조건을 만족시켜준다.
최소heap의 모든 값들 > max heap
max heap의 사이즈 = min heap의 사이즈 or min heap의 사이즈 +1
(중앙값을 구하기 위함. 전체 개수가 홀수인 경우, 중앙값은 항상 max heap에 있게 되고, 짝수인 경우에도 더 작은 값을 중앙값으로 한다하였으니 max heap에 있게된다 )
값을 넣어줄 때 마다, min heap, max heap의 top 값을 비교 → min heap의 top < max heap의 top ⇒ 값을 교환.
이렇게 하면, max heap의 top값이 중간값이 된다.
위 조건을 만족시키기 위해서는 아래와같이 해야함
Java PriorityQueue (Java Doc)
O(log n) time for the enqueing and dequeing methods (offer, poll, remove() and add) ⇒ 따라서 n 개 넣는데에 O(nlogn)
O(n) for the remove(Object) and contains(Object) methods
O(1) for the retrieval methods (peek, element, and size)
출력 문제로 인한 것이었다.
public void write(int c) throws IOException {
synchronized(this.lock) {
this.ensureOpen();
if (this.nextChar >= this.nChars) {
this.flushBuffer();
}
this.cb[this.nextChar++] = (char)c;
}
}
import java.io.*;
import java.util.*;
public class Main {
public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void solve() throws IOException{
int n = Integer.parseInt(br.readLine());
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
int temp = 0;
int min = 0 , max = 0;
StringBuilder sb = new StringBuilder();
for(int i =0;i<n;i++){
temp = Integer.parseInt(br.readLine());
// 1. 사이즈 비교
if(minHeap.size() == maxHeap.size()) {
maxHeap.add(temp);
}
else{
minHeap.add(temp);
}
if(!minHeap.isEmpty() && !maxHeap.isEmpty()&&minHeap.peek() < maxHeap.peek()){
min = minHeap.poll();
max = maxHeap.poll();
minHeap.add(max);
maxHeap.add(min);
}
sb.append(maxHeap.peek()).append("\n");
}
System.out.println(sb);
}
public static void main(String[] args)throws IOException {
solve();
}
}