Per ardua ad astra !
I'm On My Way
Per ardua ad astra !
전체 방문자
오늘
어제
  • 분류 전체보기 (126)
    • Algorithm (50)
      • 백준 (30)
      • SWEA (3)
      • JUNGOL (3)
      • Programmers (5)
      • LeetCode (2)
    • 안드로이드 개발 (6)
      • Java로 개발 (0)
      • Kotlin으로 개발 (3)
    • Spring (41)
      • Spring기본 (17)
      • JPA기본 (15)
      • JPA활용 SpringBoot 기본 (9)
      • API 개발 기본 (0)
    • 네트워크 (3)
    • 운영체제 (0)
    • Life (3)
      • 책 (0)
      • 자기계발 (1)
      • 일상 (2)
    • 노마드코더 (3)
      • python으로 웹 스크래퍼 만들기 (3)
    • 프로그래밍 언어 (17)
      • Java 기본 (2)
      • 코틀린 기본 (15)

블로그 메뉴

  • 홈
  • 방명록

인기 글

hELLO · Designed By 정상우.
Per ardua ad astra !

I'm On My Way

Algorithm

[Java] BaekJoon 2696 중앙값 구하기 (골드2) (힙에 대한 이해)

2021. 12. 8. 14:32

문제출처: https://www.acmicpc.net/problem/2696

 

2696번: 중앙값 구하기

첫째 줄에 테스트 케이스의 개수 T(1 ≤ T ≤ 1,000)가 주어진다. 각 테스트 케이스의 첫째 줄에는 수열의 크기 M(1 ≤ M ≤ 9999, M은 홀수)이 주어지고, 그 다음 줄부터 이 수열의 원소가 차례대로 주

www.acmicpc.net

 

문제이해

 

목표

어떤 수열을 읽고, 홀수번째 수를 읽을 때 마다,
지금까지 입력받은 값의 중앙값을 출력하는 프로그램을 작성하시오.

 

풀이

흐름

Queue 2개를 만든다. 

비교적 작은 수들이 모여있는 leftQueue -> 내림차순 정렬 (큰 수 먼저 나오게)
비교적 큰 수들이 모여 있는 rightQueue -> 오름차순 정렬 (작은 수 먼저 나오게)

핵심은 홀 수 일 때 각 큐의 맨 앞의 값(대표)을 비교하는 것이 핵심 !! 
-> ex) 작은놈 중 가장 큰 대표 vs 큰놈중 가장 작은 대표 
-> 홀수 일때, 중앙값은 항상 leftQueue의 대표임 

로직

1. 짝수 일 때
   그냥 오른쪽 큐에 넣음

2. 홀수 일 때
   (1)
왼쪽큐의 대표와 오른쪽 큐의 대표를 비교, 왼쪽 대표가 더 크면 대표끼리 바꿔줌. 
   (2) 왼쪽큐의 대표를 정답에 추가 

 

소스코드

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

import static java.lang.System.in;

// https://www.acmicpc.net/problem/2696
// 힙 2개를 가지고 최대한 활용할 줄 알아야 하는 문제
public class 중앙값구하기 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        int T = Integer.parseInt(br.readLine());
        StringBuilder answerBuilder = new StringBuilder();

        for (int testCase = 0; testCase < T; testCase++) {
            int N = Integer.parseInt(br.readLine());
            // 정답 개수 출력
            answerBuilder.append(N / 2 + 1).append("\n");

            // 알고리즘 시작
            PriorityQueue<Integer> leftQueue = new PriorityQueue<>(Collections.reverseOrder());
            PriorityQueue<Integer> rightQueue = new PriorityQueue<>();
            int count = 1;
            String[] strArr;

            while (N > 0) {
                strArr = br.readLine().split(" ");
                for (int i = 0; i < strArr.length; i++) {
                    int next = Integer.parseInt(strArr[i]);
                    if (count % 2 == 1) { // 홀수 일때
                        leftQueue.add(next);
                        if (!rightQueue.isEmpty()) {
                            if (leftQueue.peek() > rightQueue.peek()) {
                                int leftOne = leftQueue.poll();
                                int rightOne = rightQueue.poll();
                                rightQueue.add(leftOne);
                                leftQueue.add(rightOne);
                            }
                        }
                        answerBuilder.append(leftQueue.peek()).append(" ");
                    } else { // 짝 수 일 때
                        rightQueue.add(next);
                    }
                    count++;
                }
                if (count > 20) {
                    answerBuilder.append("\n");
                    count -= 20;
                }
                N -= 10;
            }
            answerBuilder.append("\n");
        }
        System.out.println(answerBuilder);
    }
}
저작자표시 비영리 (새창열림)
    'Algorithm' 카테고리의 다른 글
    • [Java] BaekJoon 14226. 이모티콘 (BFS) (골드5)
    • [Java] BaekJoon 3197. 백조의호수(BFS) (플레5)
    • [Java] BaekJoon 2579. 계단오르기 (DP) (실버3)
    • [Java] BaekJoon 12869. 뮤탈리스크 (골드4) (dfs) (dp)
    Per ardua ad astra !
    Per ardua ad astra !
    개발자 지망생이며 열심히 공부하고 기억하기 위한 블로그입니다.

    티스토리툴바