1. running median
우선순위 큐로 중앙값을 빠르게 구하는 방법 - running median (tistory.com)
우선순위 큐로 중앙값을 빠르게 구하는 방법 - running median
1. 개요 수열이 계속 변화할때, 이 수열의 중앙값을 어떻게 빠르게 구할 수 있을까 매번 정렬해서 중간의 값을 찾아야하는가? 최대 힙과 최소 힙을 이용하면 중앙값을 아주 쉽게 찾을 수 있다 결
deepdata.tistory.com
1) 최대힙과 최소힙 2개를 초기화
2) 최대힙의 원소의 수와 최소힙의 원소의 수가 동일하다면, 최대힙에 수를 넣어주고
3) 최대힙의 원소의 수가 최소힙의 원소의 수 + 1이라면, 최소힙에 수를 넣어준다.
즉 최대힙 > 최소힙 > 최대힙 > 최소힙 >....으로 번갈아가면서 수를 넣어준다.
4) 최대힙의 루트가 최소힙의 루트보다 크거나 같다면, 서로 교환해서, 최대힙의 루트가 항상 최소힙의 루트보다 작게 만든다
5) 이렇게 하면, 두 힙에 들어간 원소의 수가 홀수개이면 최대힙의 루트가 항상 수열의 중앙값이 된다.
2. 자바로 구현
위 알고리즘 그대로 쓰면 된다
주의할 점은 최대힙을 구성할때 -를 붙여서 넣어줘야하고, 빼서 사용할때는 -를 다시 붙여줘야하고
.peek()의 경우 힙에 원소가 0개이면 에러나므로 일단 첫 원소는 for문 밖에서 최대힙에 넣어주고 시작하자
최대힙 루트와 최소힙 루트를 교환할때는, poll()로 각각 빼서 최대힙에서 뺀건 최소힙에, 최소힙에서 뺀건 최대힙에 넣어주면 된다
import java.util.Scanner;
import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) {
// 여기에 코드를 작성해주세요.
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for(int i = 0; i < t; i++){
int m = sc.nextInt();
PriorityQueue<Integer> max_heap = new PriorityQueue<>();
PriorityQueue<Integer> min_heap = new PriorityQueue<>();
max_heap.add(-sc.nextInt());
System.out.print(-max_heap.peek() + " ");
for(int j = 1; j < m; j++){
if(max_heap.size() == min_heap.size()){
max_heap.add(-sc.nextInt());
} else {
min_heap.add(sc.nextInt());
}
if(-max_heap.peek() >= min_heap.peek()){
int max = -max_heap.poll();
int min = min_heap.poll();
max_heap.add(-min);
min_heap.add(max);
}
if (j % 2 == 0){
System.out.print(-max_heap.peek() + " ");
}
}
System.out.println();
}
}
}
'알고리즘 > 자료구조(스택,큐,해시맵)' 카테고리의 다른 글
[Java]자바로 구현하는 절댓값 우선순위 큐 (0) | 2023.03.22 |
---|---|
[Java]우선순위 큐 응용 - MN개의 조합에서 조건을 만족하는 k번째 수를 찾는 빠르게 찾는 방법 1편 (0) | 2023.03.21 |
[Java]자바 우선순위 큐 응용하기1 -뒤에서부터 생각하면 효과적으로 변하는 경우- (0) | 2023.03.20 |
우선순위 큐 재활하면서 응용력 키우기1 -카드 정렬하기, N번째 큰 수 (0) | 2023.03.18 |
스택 테크닉 익히기1 -문자열 폭발 (0) | 2023.01.29 |