백준 N번째 큰 수

KIMYEONGJUN·2025년 12월 25일
post-thumbnail

문제

내가 생각했을때 문제에서 원하는부분

첫째 줄에 N(1 ≤ N ≤ 1,500)이 주어진다.
다음 N개의 줄에는 각 줄마다 N개의 수가 주어진다.
표에 적힌 수는 -10억보다 크거나 같고, 10억보다 작거나 같은 정수이다.

첫째 줄에 N번째 큰 수를 출력한다.

내가 이 문제를 보고 생각해본 부분

입력 준비:
BufferedReader를 사용하여 표준 입력을 효율적으로 읽어온다.
N값을 입력받아 저장한다.
우선순위 큐(PriorityQueue) 초기화:
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
Java의 PriorityQueue는 기본적으로 최소 힙(Min-Heap)으로 구현된다. 
최소 힙은 항상 가장 작은 원소를 root에 두는 자료구조이다.
우리는 이 힙을 사용하여 N번째 큰 수를 찾을 것이다. 
만약 힙에 k개의 숫자가 있고, 이 힙이 최소 힙이라면, 힙의 root는 k번째로 큰 숫자가 된다.
숫자 처리:
이중 반복문을 사용하여 N개의 줄을 읽고, 각 줄에서 N개의 숫자를 StringTokenizer로 분리하여 읽는다. 
StringTokenizer는 문자열을 공백 기준으로 효율적으로 나눌 때 사용된다.
각 숫자(num)를 읽을 때마다 다음 과정을 반복한다.
minHeap.offer(num);: 현재 숫자를 힙에 추가한다.
if (minHeap.size() > N) { minHeap.poll(); }: 만약 힙의 크기가 N을 초과하면, 힙에서 가장 작은 원소(root)를 제거한다. 
이렇게 함으로써 minHeap은 항상 현재까지 만난 숫자들 중 가장 큰 N개의 숫자만 유지하게 된다.
결과 출력:
모든 N * N개의 숫자를 처리하고 나면, minHeap에는 가장 큰 N개의 숫자만 남아있다.
이때 minHeap의 가장 작은 원소(즉, minHeap.peek()으로 접근할 수 있는 원소)가 바로 N번째로 큰 숫자가 된다.

코드로 구현

package baekjoon.baekjoon_31;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

// 백준 2075번 문제
public class Main1247 {
    public static void main(String[] args) throws IOException {
        // 입력을 빠르게 처리하기 위해 BufferedReader 사용
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 첫 줄에서 N 값 읽기
        int N = Integer.parseInt(br.readLine());

        // 최소 힙 (Min-Heap) 생성. N번째 큰 수를 찾기 위함입니다.
        // PriorityQueue는 기본적으로 최소 힙으로 동작합니다.
        // 이 힙에는 항상 N개의 가장 큰 값들이 저장됩니다.
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();

        // N개의 줄을 읽으며 N*N개의 숫자를 모두 처리합니다.
        for (int i = 0; i < N; i++) {
            // 한 줄에 N개의 숫자가 공백으로 구분되어 있으므로 StringTokenizer를 사용합니다.
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < N; j++) {
                // 각 숫자를 정수로 변환하여 읽습니다.
                int num = Integer.parseInt(st.nextToken());

                // 현재 숫자를 최소 힙에 추가합니다.
                minHeap.offer(num); // .add()와 유사하지만, 힙의 크기가 제한될 때 .offer()가 조금 더 유용할 수 있습니다.

                // 만약 힙의 크기가 N을 초과하면, 가장 작은 원소 (힙의 루트)를 제거합니다.
                // 이렇게 하면 minHeap은 항상 현재까지의 수들 중 가장 큰 N개의 숫자만 보유하게 됩니다.
                // 힙의 크기가 N개일 때, 힙의 루트(가장 작은 값)가 N번째 큰 값이 됩니다.
                if (minHeap.size() > N) {
                    minHeap.poll(); // 힙에서 가장 작은 원소를 제거합니다.
                }
            }
        }

        // 모든 숫자를 처리한 후, 힙에 남아있는 가장 작은 원소 (힙의 루트)가 N번째 큰 수입니다.
        System.out.println(minHeap.peek());

        // BufferedReader 리소스 해제
        br.close();
    }
}

마무리

코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.

profile
Junior backend developer

0개의 댓글