본문 바로가기

Algorithm

[프로그래머스] 이중우선순위큐(Python, Java)

반응형

https://programmers.co.kr/learn/courses/30/lessons/42628

 

코딩테스트 연습 - 이중우선순위큐

 

programmers.co.kr

문제 설명

이중 우선순위 큐는 다음 연산을 할 수 있는 자료구조를 말합니다.

명령어 수신 탑(높이)
I 숫자 큐에 주어진 숫자를 삽입합니다.
D 1 큐에서 최댓값을 삭제합니다.
D -1 큐에서 최솟값을 삭제합니다.

이중 우선순위 큐가 할 연산 operations가 매개변수로 주어질 때, 모든 연산을 처리한 후 큐가 비어있으면 [0,0] 비어있지 않으면 [최댓값, 최솟값]을 return 하도록 solution 함수를 구현해주세요.

제한사항

  • operations는 길이가 1 이상 1,000,000 이하인 문자열 배열입니다.
  • operations의 원소는 큐가 수행할 연산을 나타냅니다.
    • 원소는 “명령어 데이터” 형식으로 주어집니다.- 최댓값/최솟값을 삭제하는 연산에서 최댓값/최솟값이 둘 이상인 경우, 하나만 삭제합니다.
  • 빈 큐에 데이터를 삭제하라는 연산이 주어질 경우, 해당 연산은 무시합니다.

입출력 예

operations return
[I 16,D 1] [0,0]
[I 7,I 5,I -5,D -1] [7,5]

입출력 예 설명

16을 삽입 후 최댓값을 삭제합니다. 비어있으므로 [0,0]을 반환합니다.
7,5,-5를 삽입 후 최솟값을 삭제합니다. 최대값 7, 최소값 5를 반환합니다.

풀이 설명

1. 제목 그대로 우선순위 큐를 이용한다.

2. 기본적으로 연산을 저장할 최소힙을 만든다.

3. operations 탐색

  3-1. 연산자가 I면 answer에 숫자 삽입

  3-2. D 1이면 최소힙 배열의 최댓값을 제거한다. (파이썬은 최소힙을 리스트처럼 사용할 수 있기 때문에 가능)

  3-3. D -1이면 최소힙 배열의 최솟값을 제거한다.

4. answer가 비어있지 않으면 answer의 최댓값과 최솟값만 리턴하고, 비어있으면 [0,0]을 리턴한다.

Python3

import heapq
def solution(operations):
    answer = []
    heapq.heapify(answer)
    for op in operations:
        if op.startswith("I"):
            heapq.heappush(answer, int(op[2:]))
        else:
            if answer:
                if op == "D 1":
                    answer.remove(max(answer))
                else:
                    heapq.heappop(answer)
                
    if answer:
        return [max(answer),min(answer)]
    else:
        return [0,0]

Java 풀이설명

1. Java는 파이썬과 달리 힙(우선순위큐)에 리스트 함수를 사용할 수 없기 때문에

   최소힙과 최대힙 두 개를 만든다.

2. operations를 탐색한다.

  2-1. 연산자가 I면 최소힙과 최대힙 모두에 숫자를 삽입한다.

  2-2. 연산자가 D 1이고 힙이 비어있지 않으면 minq에서 maxq.poll()한 숫자를 제거한다. (이러면 maxq와 minq 모두 최댓값이 제거됨)

  2-3. 연산자가 D -1이고 힙이 비어있지 않으면 maxq에서 minq.poll()한 숫자를 제거한다.

3. 힙이 비어있지 않으면 maxq.poll()과 minq.poll()을 리턴하고, 비어있으면 [0,0]을 리턴한다.

Java

import java.util.PriorityQueue;
import java.util.Collections;

class Solution {
    public int[] solution(String[] operations) {
        int[] answer = {0,0};
        PriorityQueue<Integer> minq = new PriorityQueue<>();
        PriorityQueue<Integer> maxq = new PriorityQueue<>(Collections.reverseOrder());
        
        for(String op : operations){
            String[] arr = op.split(" ");
            
            switch(arr[0]){
                case "I":
                    minq.add(Integer.parseInt(arr[1]));
                    maxq.add(Integer.parseInt(arr[1]));
                    break;
                case "D":
                    if(minq.size() > 0){
                        if(arr[1].equals("1"))
                            minq.remove(maxq.poll());
                        else
                            maxq.remove(minq.poll());
                    }
                    break;
            }
        }
            
        if(minq.size() >= 2){
            answer[0] = maxq.poll();
            answer[1] = minq.poll();
        }
        return answer;
    }
}
반응형