[프로그래머스] LV.3 이중우선순위큐 (JS)

KG·2021년 4월 7일
2

알고리즘

목록 보기
3/61
post-thumbnail

문제

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

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

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

제한

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

입출력 예시

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

풀이

카테고리가 힙(Heap)에 해당되니 힙을 이용해서 풀면 베스트겠지만, 문제는 JS는 Heap 자료구조를 기본적으로 제공해주지 않는다. (Python3에서는 heapify 또는 heapq, JAVA에서는 PriorityQueue등의 라이브러리가 있고, 보통 코딩테스트에서 모두 정상적으로 사용가능하다) 따라서 직접 해당 자료구조를 구현해서 이를 이용해 풀어야 한다. (이런 문제점말고도 JS는 알고리즘을 풀기에 적절한 언어는 아니다. 근데 왜 나는 JS를 고집하는걸까?)

그런데 해당 문제는 굳이 Heap 자료구조를 이용하지 않고 그때마다 최댓값 또는 최솟값을 찾아서 삭제하는 식으로 코딩해도 모튼 테스트케이스를 통과한다. 관련해서 질문게시판도 그리고 다른 사람의 풀이에도 왜 힙을 쓰지 않고도 통과하는지에 대한 의문이 많은걸 보아 리뉴얼되지 않을까도 싶다. 만약 리뉴얼된다면 아래의 코드는 통과하지 않을 가능성이 매우 높다.

문제의 의도는 Heap을 구현해서 최대힙/최소힙을 적절히 동기화하여 해결하든, Heap Sort 방식으로 해결하든 식의 방향이겠지만 그냥 단순히 구현하도록 하자. 코드만 봐도 쉽게 이해할 수 있기에 설명은 주석으로 대체한다. 추후 문제가 리뉴얼되거나 정말 Heap 자료구조를 사용해야 하는 경우에 자바스크립트에서 Heap을 구현하는 포스팅을 해보겠다.


코드

function solution(operations) {
    const heap = [];
    const op = operations.map(operation => operation.split(' '));
  	// 입력된 명령어를 공백(' ')을 기준으로 분할한다.
  	// 따라서 배열[0] = 명령어, 배열[1] = 숫자로 접근할 수 있다.
    
    op.forEach(num => {
        if(num[0] === 'I') {	// 명령어가 I라면 데이터 삽입
            heap.push(Number(num[1]))
        }
        else {	// 그 외의 경우, 즉 명령어가 D인 경우
            const findValue = (num[1] === '1' ? Math.max : Math.min)(...heap);
          	// 숫자가 1이라면 max값을, -1이라면 min값을 적용해서
            const delIdx = heap.indexOf(findValue);
          	// 찾고자 하는 값의 인덱스를 찾아서
            heap.splice(delIdx, 1);
          	// (이름만 heap인) 배열에서 해당 인덱스의 원소를 제거
        }
    })
    
    return heap.length ? [Math.max(...heap), Math.min(...heap)] : [0, 0];
}

위 코드에서 Math.max(...heap) 또는 heap.indexOf(value) 등은 모두 O(n)의 시간이 소요된다. 따라서 정석적인 Heap 자료구조를 사용할 때 보다 시간복잡도가 높다. 즉 다시한번 말하지만 Heap이 아니라 일반적인 정렬 알고리즘으로 해결했다.


출처

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

profile
개발잘하고싶다

0개의 댓글