priority_queue 우선순위 큐 활용

2025. 1. 6. 12:36·공부/Code Cata

명예의 전당의 최하위 점수를 매일 기록해 반환하는 문제이다.

즉 k가 3이라고 한다면 탑3를 매일 선정하고 그 중 최하위 점수를 answer 리스트에 저장해 반환하면 되는 문제인데 예시 경우에는 올바르게 작동했지만, 여러 테스트 케이스를 채첨해봤을 때 오류가 발생했었다.

 

 

*초기 오답 코드

더보기
#include <string>
#include <vector>
#include <queue>

using namespace std;

vector<int> solution(int k, vector<int> score) {
    vector<int> answer;
    priority_queue<int, vector<int>, greater<int>> pq;
    
    for(int i = 0; i < score.size(); ++i)
    {
        // 현재 score가 명예의 전당에 들지 못 할 경우
        if(pq.size() > 0 && score[i] < pq.top())
        {
            // 현재 명예의 전당 최하위 점수 저장
            answer.push_back(pq.top());
            continue;
        }
        // pq의 사이즈가 k 이상
        if(pq.size() >= k)
        {
            pq.pop();
            pq.push(score[i]);
        }
        // pq의 사이즈가 k 미만
        else
        {
            pq.push(score[i]);
        }
        
        // 명예의 전당 최하위 점수 저장
        answer.push_back(pq.top());
    }
    
    return answer;
}
  • 문제가 되었던 부분은 for문 안에 첫 번째 조건문 score[i] < pq.top()이었다.
  • 간과하고 있던 부분은 명예의 전당의 크기는 k이고, 이 k의 크기를 초과하지 않을 때는 모든 값이 명예의 전당 list에 저장되어야 하는데, 현재 코드에선 만약 첫 번째로 명예의 전당에 10의 값이 들어오고 두 번째에 1의 값이 들어온다면 list에 값이 저장되지 않을 것이고 결과적으로 k의 값이 정확하게 카운팅 되지 않는 문제가 발생한다.

 

 

*수정된 코드

더보기
#include <string>
#include <vector>
#include <queue>

using namespace std;

vector<int> solution(int k, vector<int> score) {
    vector<int> answer;
    priority_queue<int, vector<int>, greater<int>> pq;
    
    for(int i = 0; i < score.size(); ++i)
    {
        // pq의 사이즈가 k 이상
        if(pq.size() >= k)
        {
            // 현재 score가 pq의 최소 값보다 클 때만 명예의 전당에 값 저장
            if(score[i] > pq.top())
            {
                pq.pop();
                pq.push(score[i]);    
            }
        }
        // pq의 사이즈가 k 미만
        else
        {
            pq.push(score[i]);
        }
        
        // 명예의 전당 최하위 점수 저장
        answer.push_back(pq.top());
    }
    
    return answer;
}
  • 명예의 전당 list에 k만큼 값들이 차있을 때만 score[i] > pq.top()  점수가 명예의 전당에 있는 최소 점수보다 크면 값을 갱신하도록 수정하였다.
  • 수정된 코드는 list의 사이즈가 k가 되기 전에는 값을 무조건 list에 저장하게 되고, k 이상이면 list의 최소 값보다 큰 값만 저장될 수 있음으로 문제에 맞게 해결되었다.

 

 

*multiset으로 문제 풀이

더보기
#include <string>
#include <vector>
#include <set>

using namespace std;

vector<int> solution(int k, vector<int> score) {
    vector<int> answer;
    multiset<int> topList;
    
    for(int i = 0; i < score.size(); ++i)
    {
        // k를 초과하지 않을 때
        if(i < k)
        {
            topList.insert(score[i]);
        }
        // k를 초과할 때
        else 
        {
            // 현재 스코어가 topList의 최소 값보다 크다면
            if(score[i] > *topList.begin())
            {
                topList.erase(topList.begin());
                topList.insert(score[i]);
            }
        }
        
        //현재 topList의 최소 값을 answer에 저장
        answer.push_back(*topList.begin());
    }
    
    return answer;
}
  • 다른 사람 문제 풀이를 보던 중 multiset으로 해결한 사람이 있어 참고해봤다.

 

그렇다면 priority_queue와 multiset 중에 어떤 컨테이너로 문제를 해결하는게 좋을까?

 

두 컨테이너 모두 삽입과 삭제 연산이 O(log n)으로 빠른 속도를 가지고 있다.

priority_queue는 내부 요소에 직접 접근하거나 특정 요소를 삭제하는 연산이 불가능하다.(우선 순위에 따른 삭제는 가능)

multiset은 반복자로 특정 값이 몇 번 저장되어있는지 확인 가능하고 특정 값을 삭제하거나 범위 삭제를 할 수 있다.

 

이 문제에서는 매일 "명예의 전당"의 최하위 점수만 발표하고, 새로운 점수를 추가하거나 교체하는 연산이 중심임으로 priority_queue가 더 적합해 보인다.

만약 특정 점수의 존재 여부를 확인하거나 특정 값을 삭제하는 등 추가적인 메서드 기능들이 필요하다고 한다면 multiset을 활용하는게 더 좋아보인다.

 

https://dong-grae.tistory.com/92

 

priority_queue

우선 순위 큐 priority_queue는 queue와 비슷하지만, 각 요소가 우선순위를 가지며 우선순위가 높은 요소가 먼저 처리되는 자료구조이다. 일반적인 FIFO(First Int First Out) 구조의 queue와는 다르게, 요소의

dong-grae.tistory.com

 

'공부 > Code Cata' 카테고리의 다른 글

모의고사 / 완전 탐색  (1) 2025.01.08
과일장수  (0) 2025.01.07
대칭되는 문자열 만들기  (0) 2025.01.03
람다 함수로 사용자 설정 정의해 정렬하기  (0) 2025.01.01
문자열에서 영문 숫자 변환하기  (0) 2024.12.31
'공부/Code Cata' 카테고리의 다른 글
  • 모의고사 / 완전 탐색
  • 과일장수
  • 대칭되는 문자열 만들기
  • 람다 함수로 사용자 설정 정의해 정렬하기
동그래님
동그래님
  • 동그래님
    개발자 동그래
    동그래님
  • 전체
    오늘
    어제
    • 분류 전체보기 (205) N
      • 공부 (51)
        • Code Cata (50)
      • 내배캠 (146) N
        • TIL (50)
        • C++ (37)
        • Unreal Engine (48)
        • GAS(Gameplay Ability System.. (11) N
      • Project (7)
        • Gunfire Paragon (5)
        • Arena Fighters (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    동그래님
    priority_queue 우선순위 큐 활용
    상단으로

    티스토리툴바