1. 💎 문제
1927번: 최소 힙
첫째 줄에 연산의 개수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 연산에 대한 정보를 나타내는 정수 x가 주어진다. 만약 x가 자연수라면 배열에 x라는 값을 넣는(추가하는) 연산이고, x가 0
www.acmicpc.net
2. 🤔어떻게 풀까
저번에 풀어봤던 문제랑 비슷해서 그때 처럼 `TreeMap`을 써서 풀기로 했다.
조건은 가장 작은 수를 단 번에 꺼낼 수 있어야 한다는 것과 중복값을 포함할 수 있어야 한다는 것이다.
가장 작은 수를 앞에서 꺼내기 위해 정렬을 한 후 넣으면 시간 초과가 난다.
TreeSet 또는 TreeMap
삽입과 동시에 정렬을 해서 넣어준다. 이진 탐색으로 구현되어 있다.
-정렬 방법 변경-
생성할 때 Compartor를 넣어주어 원하는 정렬을 할 수 있다.
TreeSet<Integer> ts1 = new TreeSet<>(Comparator.reverseOrder())
구현 코드는 아래와 같다.
문제는 맞췄지만, 너무 1100ms라는 너무 많은 시간이 걸렸다. 그래서 시간이 짧은 다른 사람의 코드를 보았다.
class Main {
static final int MIN = 0;
static final int MAX = 100_000;
public static void main(String args[]) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 연산의 개수
int N = Integer.parseInt(br.readLine());
TreeMap<Integer, Integer> treeMap = new TreeMap<>();
for(int i =0; i<N; i++){
int num = Integer.parseInt(br.readLine());
// 가장 작은 값 출력
if(num == 0) {
try {
int key = treeMap.firstEntry().getKey();
int value = treeMap.firstEntry().getValue();
if (value > 1) {
treeMap.replace(key, value - 1);
} else {
treeMap.remove(key);
}
bw.write(key + "\n");
} catch (IllegalStateException e) {
bw.write(0 + "\n");
} catch (NullPointerException e){
bw.write(0 + "\n");
}
continue;
}
// 요소 추가
int value = treeMap.getOrDefault(num, 0) +1;
treeMap.put(num, value);
}
bw.flush();
bw.close();
br.close();
}
}
3. 또 다른 방법 : 우선 순위 큐 이용
바로 우선 순위 큐를 이용한 방법이다.
우선순위 큐(PriorityQueue)
중복을 포함하여, 낮은 수를 가장 높은 기준으로 삽입한다.
생성할 때 매개변수로 Comprator를 넣어 정렬 기준을 바꿀 수 있다.
//높은 숫자가 우선 순위인 int 형 우선순위 큐 선언
PriorityQueue<Integer> priorityQueueHighest = new PriorityQueue<>(Collections.reverseOrder());
문제의 조건대로 이미 구현되어 있기 때문에, 큐가 비어있을 때 적절한 처리만 해주면 된다.
코드는 아래와 같다.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.*;
class Main {
public static void main(String args[]) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 연산의 개수
int N = Integer.parseInt(br.readLine());
PriorityQueue<Integer> pq = new PriorityQueue<>();
for(int i =0; i<N; i++){
int num = Integer.parseInt(br.readLine());
// 가장 작은 값 출력
if(num == 0) {
if(pq.isEmpty()){
bw.write(0+"\n");
}else{
bw.write(pq.poll()+"\n");
}
continue;
}
// 요소 추가
pq.add(num);
}
bw.flush();
bw.close();
br.close();
}
}
시간은 376ms로 약 800ms나 줄었다.
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 리모컨 : 1107 - 완전 탐색 (G5) (1) | 2023.11.20 |
---|---|
[D3] 18662 등차수열 만들기 (0) | 2023.11.18 |
[S1] Z : 1074 - 분할정복 (0) | 2023.11.17 |
[S2] 유기농 배추 : 1012 - BFS (0) | 2023.11.17 |
[D2] 파리퇴치 - 구간 합 (1) | 2023.11.13 |