ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프로그래머스] 이중 우선순위 큐 Java 풀이
    문제풀이/프로그래머스 2021. 12. 27. 01:23
    반응형

    이 글은 혼자 학습한 내용을 바탕으로 작성되었습니다.

    틀리거나 잘못된 정보가 있을 수 있습니다.

    댓글로 알려주시면 수정하도록 하겠습니다.


    1. 문제

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

    명령어수신 탑(높이)

    I 숫자 큐에 주어진 숫자를 삽입합니다.
    D 1 큐에서 최댓값을 삭제합니다.
    D -1 큐에서 최솟값을 삭제합니다.

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

    2. 입력

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

    3. 예제

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

    4. 풀이

    이번 문제는 문제에서 주어진 방법을 코드로 작성하면 되는 문제였습니다.

     

    문제에서 I의 경우는 숫자를 큐에 입력하는 연산자이며 D의 경우는 양수이면 최댓값을 제거하고 음수인 경우는 최솟값을 제거하는 명령어라고 정의가 되어 있습니다.

     

    그러므로 정렬이 가능한 자료구조를 사용하고자 우선순위 큐를 사용하였습니다.

     

    하지만 우선순위 큐의 경우 내림차순인 경우는 최댓값을 앞쪽으로 정렬하며 오름차순인 경우는 최솟값을 앞쪽으로 정렬하기에 2개의 우선순위 큐를 선언하여 하나는 오름차순으로 정렬을 하나는 내림차순으로 정렬하도록 큐를 선언한 뒤

     

    I 명령어의 경우는 2개의 우선순위 큐에 숫자를 입력합니다.

     

    D의 경우는 음수인지 양수인지 판단하기 전 큐가 비어있는지 없는지 확인합니다. 2개의 큐의 경우 입력되어 있는 수의 개수는 항상 동일하므로 2개의 큐 중 아무 큐나 비어있는지 확인을 진행하면 됩니다.

     

    확인 후 만약 큐가 비어있지 않다면 값이 음수인지 양수인지 판단합니다.

     

    음수인 경우는 최솟값을 제거하는 것이므로 오름차순 큐에서 가장 앞의 값을 가지고 온 뒤 내림차순 큐에서 해당 수를 제거합니다.

     

    양수인 경우는 반대로 최댓값을 제거하는 것으로 내림차순 큐에서 가장 앞의 값을 가지고 온 뒤 오름차순 큐에서 해당 수를 제거합니다.

     

    이렇게 입력으로 주어진 명령어 리스트를 반복하면 2개의 큐에 최종적으로 남아있는 수가 있을 것입니다.

     

    만약 2개의 큐 중 어떠한 큐든 비어있다면 [0, 0]을 반환하고

     

    만약 비어있지 않다면 각 큐에서 가장 앞에 있는 수를 가져와 배열에 넣어 반환하면 이번 문제는 아주 쉽게 풀 수 있습니다.

     

    5. 코드

    전체 코드는 Git에 있습니다.

    PriorityQueue<Integer> reverseQueue = new PriorityQueue<>(Comparator.reverseOrder());
    PriorityQueue<Integer> queue = new PriorityQueue<>();
    
    for (String sub : operations) {
    	String[] split = sub.split(" ");
    	int num = Integer.parseInt(split[1]);
    
    	switch (split[0]) {
    		case "I":
    			reverseQueue.offer(num);
    			queue.offer(num);
    			break;
    		case "D":
    			if (!reverseQueue.isEmpty()) {
    				if (num < 0)
    					reverseQueue.remove(queue.poll());
    				else
    					queue.remove(reverseQueue.poll());
    			}
    			break;
    	}
    }
    
    int[] answer = new int[2];
    
    if(!reverseQueue.isEmpty()) {
    	answer[0] = reverseQueue.poll();
    	answer[1] = queue.poll();
    }
    
    return answer;
    반응형

    댓글

Designed by Tistory.