프로그래머스 - 이중우선순위큐

well-life-gm·2021년 12월 17일
0

프로그래머스

목록 보기
84/125

프로그래머스 - 이중우선순위큐

min_heap, max_heap을 2개 관리하면서 숫자가 insert될 때마다 각 숫자의 index_count를 증가시켜주고, 이를 관리하기 위해 map을 사용한다. (map의 index_count가 의미하는 것은 현재 heap에 존재하는 key에 해당하는 숫자의 갯수이다)

그 후 Delete가 발생할 때에는 max_heap 혹은 min_heap에서 top을 pop해주고, map의 index_count를 감소시킨다. 추가적으로 map에서 내 숫자에 해당하는 index_count와 heap의 top이 갖는 index(insert시 부여되며, monotonic increase하는)가 일치할 때 까지 pop해준다.

코드를 보니 set을 이용하면 더 짧은 코드로 완성할 수 있는 것 같다.
set은 ordered이기 때문에 insert시 logN으로 insert를 해주기 때문에 heap과 시간복잡도가 똑같으며, iteratable하기 때문에 begin, end를 통해서 min값과 max값을 동시에 접근할 수 있다. 다음엔 set을 사용해봐야겠다.

코드는 아래와 같다.

#include <string>
#include <vector>
#include <queue>
#include <map>

using namespace std;

#define pii pair<int, int>

map<int, int> m;
vector<int> solution(vector<string> operations) {
    vector<int> answer;
    
    priority_queue<pii, vector<pii>, greater<pii>> min_pq;
    priority_queue<pii, vector<pii>> max_pq;
    
    for(auto it : operations) {
        if(it[0] == 'I') {
            string tmp(it.begin() + 2, it.end());
            int num = stoi(tmp);
            m[num]++;
            int idx = m[num];
            min_pq.push( {num, idx} );
            max_pq.push( {num, idx} );
        } else if(it[0] == 'D') {
            if(it[2] == '1') {
                while(1) {
                    if(max_pq.empty())
                        break;
                    pii pq_val = max_pq.top();
                    if(m[pq_val.first] != pq_val.second) {
                         max_pq.pop();
                    } else {
                        m[pq_val.first]--;
                        break;
                    }
                }
            } else {
                while(1) {
                    if(min_pq.empty())
                        break;
                    pii pq_val = min_pq.top();
                    if(m[pq_val.first] != pq_val.second) {
                         min_pq.pop();
                    } else {
                        m[pq_val.first]--;
                        break;
                    }
                }
            }
        }
    }
    
    int max_val = 0;
    int min_val = 0;
    while(1) {
        if(max_pq.empty())
            break;
        pii pq_val = max_pq.top(); max_pq.pop();
        if(pq_val.second > m[pq_val.first]) 
            continue;
        max_val = pq_val.first;
        break;
    }
    while(1) {
        if(min_pq.empty())
            break;
        pii pq_val = min_pq.top(); min_pq.pop();
        if(pq_val.second > m[pq_val.first]) 
            continue;
        min_val = pq_val.first;
        break;
    }
    answer.push_back(max_val);
    answer.push_back(min_val);
    
    return answer;
}

결과

profile
내가 보려고 만든 블로그

0개의 댓글