일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 2294
- GeeksForGeeks
- 티스토리챌린지
- C++
- Programmers
- DeferredRendering
- softeer
- directx
- 언리얼엔진5
- 백준
- algorithm
- Frustum
- RVO
- const
- DirectX11
- RootMotion
- C
- 오블완
- winapi
- 프로그래머스
- NRVO
- 1563
- 팰린드롬 만들기
- UnrealEngine5
- IFileDialog
- UnrealEngine4
- baekjoon
- Unreal Engine5
- UE5
- 줄 세우기
- Today
- Total
Game Develop
[Algorithm] Programmers :: 이중우선순위큐 본문
https://programmers.co.kr/learn/courses/30/lessons/42628?language=cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
vector<string> split(string str, char Delimiter) {
istringstream iss(str); // istringstream에 str을 담는다.
string buffer; // 구분자를 기준으로 절삭된 문자열이 담겨지는 버퍼
vector<string> result;
// istringstream은 istream을 상속받으므로 getline을 사용할 수 있다.
while (getline(iss, buffer, Delimiter))
{ result.push_back(buffer); // 절삭된 문자열을 vector에 저장
}
return result;
}
vector<int> solution(vector<string> operations) {
// I 숫자 : 주어진 숫자를 삽입
// D 1 : 큐에서 최댓값 삭제
// D -1 : 큐에서 최솟값을 삭제
vector<int> answer;
vector<string> temp;
int count = 0;
priority_queue<int, vector<int>, greater<int> > minPQ;
priority_queue<int, vector<int>, less<int> > maxPQ;
for (int i = 0; i < operations.size(); i++)
{
temp = split(operations[i], ' ');
string operation = temp[0];
int num = stoi(temp[1]);
if (operation == "I")
{
minPQ.push(num);
maxPQ.push(num);
count++;
}
if (operation == "D")
{
if (num == 1 && count > 0) // 최댓값 삭제
{
maxPQ.pop();
count--;
}
if (num == -1 && count > 0) // 최소값 삭제
{
minPQ.pop();
count--;
}
}
if (count == 0) // count가 0이면, 두 큐에는 원소가 한개도 없어야한다. 그러므로 다 비워준다.
{
while (!maxPQ.empty())
{
maxPQ.pop();
}
while (!minPQ.empty())
{
minPQ.pop();
}
}
}
if (count == 0)
{
answer.push_back(0);
answer.push_back(0);
}
else
{
answer.push_back(maxPQ.top());
answer.push_back(minPQ.top());
}
return answer;
}
|
cs |
이중우선순위큐라는 새로운 유형의 문제다. string으로 주어지는 명령어를 토대로 작업을 수행하다가 최종적으로 남은 큐의 최대값,최소값을 리턴하면 된다. 한개만 남았으면 그 한개가 최대값이자 최소값이고 아예 큐가 비어있다면 0,0을 리턴하면 된다. 공백기준 문자열 나누기는 많은 예제가 있으니 알아서 나누면 된다.
위 코드에서는 istringstream을 사용해서 나눴지만, 이 문제같은 경우 공백이 무조건 1번째 인덱스에 있기 때문에 substr을 이용해서 0번째를 바로 명령어로 추출하고 1번째 이후부터 string의 size()-1까지를 숫자로 추출하면 된다.
이 문제는 기준이되는 우선순위큐 한개(이하 standPQ)를 서로 반대쪽 우선순위큐(최대값,최소값) 두개로 표현해서 해결한다. 즉, maxPQ.top()과 minPQ.top() 은 standPQ의 서로 양쪽 끝이다.(PQ는 priority queue이다.)
위 코드에서 count는 standPQ의 실제 원소개수라고 생각하면 된다. 그렇기때문에 I명령의 작업을 수행할 때(아마 Input의 약자이지 않을까 싶다) maxPQ와 minPQ에 각각 숫자를 넣더라도 count는 1만 증가다.
실제로 standPQ에는 한개만 들어가는 형식이기 때문이다.
D 1과 D -1은 각각 최대값,최소값 삭제이기 때문에 해당사항에 맞는 큐에서 pop을 한다. 당연히 내용물이 있어야 pop을 하기 때문에 count값이 0 초과일때 해당 작업을 수행한다. 일련의 명령을 수행했는데 count == 0이라면 standPQ에는 원소가 한개도 없다는 뜻이다. 그러면 maxPQ와 minPQ에도 원소가 있어서는 안된다. 두 큐는 standPQ를 서로 반대쪽으로 표현한 PQ이기 때문이다. 그렇기 때문에 count == 0이라면 두 큐를 깔끔하게 비워주자.
위의 로직으로 모든 명령을 수행하면 standPQ에 원소가 없던가, 1개이상이 있던가 할 것이다.
원소가 없다면 그냥 0,0을 넣어 리턴시키면 되고 1개이상이라면 각 큐의 top을 넣어 리턴시키면 된다.
standPQ에 원소가 1개라면, 각 큐에는 그 원소가 무조건 들어있다. 그래서 그대로 top을 넣어 리턴시키면 동일한 값을 리턴하기 때문에 문제가 생기지 않는다.
코드가 잘 이해가 안된다면, 이미 언급했다시피 maxPQ,minPQ는 그저 standPQ 한개를 각 반대쪽에서 표현한 두개의 큐일 뿐이고, count는 standPQ의 원소개수라는것만 인지하고 코드를 보면 이해가 된다. 사실 코드는 아주 단순하니까..
'Algorithm > Programmers' 카테고리의 다른 글
[Algorithm] Programmers :: 로또의 최고순위와 최저순위 (0) | 2022.07.13 |
---|---|
[Algorithm] Programmers :: 뉴스클러스터링 (0) | 2022.07.08 |
[Algorithm] Programmers :: 디스크 컨트롤러 (CPU스케줄링 비선점형 SJF알고리즘) (0) | 2022.06.06 |
[Algorithm] Programmers :: 게임 맵 최단거리 (0) | 2022.06.02 |
[Algorithm] Programmers :: 단속카메라 (0) | 2022.05.28 |