큐 문제
programmers.co.kr/learn/courses/30/lessons/42587
[문제 풀이]
원형으로 계속 돌아가는 문서 중 우선순위가 가장 높은 것을 먼저 출력하는 문제입니다.
원형으로 문서를 계속 돌리고 확인해야 하므로 큐를 써야 한다고 생각할 수 있습니다.
가장 직관적으로 생각해보면 우선 배열을 순회하면서 1~9까지의 중요도가 몇 개씩 있는지 확인하고 큐 안에 문서에 대한 정보를 넣어야 합니다.
구해야 하는 답이 위치를 기반으로 찾게 됩니다.
그러므로 큐 안에 넣을 문서에 대한 정보는 위치가 필수적으로 들어갑니다.
중요도까지 넣어도 되지만 위치를 넣었다면 그 위치에 대한 중요도를 priorities배열로 구할 수 있기 때문에 넣지 않아도 좋습니다.
예를 들어 priorities가 1 1 3 6 6 7 8 8 8 9처럼 주어졌다면
큐는 아래 두 표 중 하나와 같고
[위치만 저장한 경우] → 이 경우는 priorities배열로 중요도를 불러와야 함
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
[위치와 중요도를 묶어서 저장한 경우]
[0, 1] | [1, 1] | [2, 3] | [3, 6] | [4, 6] | [5, 7] | [6, 8] | [7, 8] | [8, 8] | [9, 9] |
중요도를 기록한 배열은 아래와 같습니다.
중요도 (i) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
개수 (arr[i]) | 2 | 0 | 1 | 0 | 0 | 2 | 1 | 3 | 1 |
이제 중요도 k를 9부터 1까지 확인하면서 남은 중요도의 개수 arr[k]가 0이라면 k를 낮춰가고, 그렇지 않다면 현재 중요도 k인 문서가 나올 때까지 큐의 front를 제거하고 다시 큐에 넣는 작업을 반복하여 가장 마지막으로 보내줍니다.
현재 중요도 k인 문서가 나왔다면 arr[k]를 1씩 낮추고 현재 문서를 큐에서 빼버려서 인쇄했음을 확정하면 됩니다.
문서를 인쇄할 때마다 count를 1씩 증가시키고 인쇄한 문서가 location에서 원하는 위치와 같았다면 반복문을 종료하고 count를 return 하면 됩니다.
그러므로 count를 저장할 변수를 한 개 만들어 줍시다.
모든 문서에 대해 큐를 돌리는 것이 비효율적일 수 있으므로 시간 복잡도를 구해봅시다.
문서를 한 바퀴 돌리면서 현재 중요도의 문서를 빼내는 작업을 진행합니다.
즉 모든 중요도 p에 대해 N개 이하의 문서를 한 바퀴 돌리면서 확인하므로 $O(Np)$의 시간 복잡도를 갖는다는 것을 알 수 있습니다.
대기 목록 N이 100 이하이고 중요도 p가 9 이하이므로 해당 풀이로도 빠른 시간 안에 구할 수 있습니다.
문제가 큐를 사용하는 문제라는 것을 납득하기 쉬워서 나름 간단한 문제였습니다.
[소스 코드] / C++
#include <string>
#include <vector>
#include <queue>
using namespace std;
int solution(vector<int> priorities, int location) {
int answer = 0, N = priorities.size();
int countPrior[10] = {0, };
queue<pair<int, int>> q;
for (int i = 0; i < N; i++) {
int p = priorities[i];
q.push(make_pair(i, p));
++countPrior[p];
}
for (int p = 9; p > 0; ) {
if (countPrior[p] == 0) {
--p;
continue;
}
pair<int, int> cur = q.front();
q.pop();
if (cur.second == p) {
++answer;
--countPrior[p];
if (cur.first == location) break;
} else q.push(cur);
}
return answer;
}
[메모]
- c++의 배열을 초기화할 때는 fill, fill_n을 사용하는 것이 좋다. memset이 가능하다면 memset의 퍼포먼스를, 불가능하다면 iterator로 초기화를 해주는 함수
- fill(iter, iter, val), fill_n(iter, len, val)
- c++에서 배열의 값을 일부만 지정해주어도 나머지는 0으로 초기화가 된다. 위의 int arr[10] = {0, }과 같은 방법
좋은 자료
www.soen.kr/lecture/ccpp/cpp4/42-2-2.htm
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스 코딩테스트 고득점 Kit - 힙(Heap)] 디스크 컨트롤러 (0) | 2021.03.08 |
---|---|
[프로그래머스 코딩테스트 고득점 Kit - 힙(Heap)] 더 맵게 (0) | 2021.03.04 |
[프로그래머스 코딩테스트 고득점 Kit - 스택/큐] 기능개발 (0) | 2021.03.01 |
[프로그래머스 코딩테스트 고득점 Kit - 스택/큐] 주식가격 (0) | 2021.02.28 |
[프로그래머스 코딩테스트 고득점 Kit - 스택/큐] 다리를 지나는 트럭 (0) | 2021.02.27 |