문제 : https://programmers.co.kr/learn/courses/30/lessons/42884
풀이
그리디 알고리즘을 이용하여야 한다.
여러 방법이 있겠으나 우선순위 큐를 이용하여 풀었다.
routes를 첫항을 기준으로 오름차순 정렬하면
[[-20,15], [-18,-13], [-14,-5], [-5,-3]]
여기서 [-20,15], [-18,-13], [-14,-5]는 [-14,-13] 범위에서 중복된다.
그러므로 위 세개는 -14, -13 둘 중 하나에서 카메라를 설치하고 -5~-3의 범위에서 카메라를 또 하나 설치한다.
시간이 -30000부터 계속 증가하다가 -20이 되면 [-20, 15]를 만난다. 그럼 [-20, 15]를 우선순위 큐에 넣는다.
우선순위 큐는 현재 고속도로에 존재하는 차들이며 고속도로에서 나가는 시간의 최소힙을 기준으로 한다.
시간이 또 증가하다가 -18이 되면 [-18, -13]을 만나서 역시 우선순위 큐에 넣는다.
마찬가지로 시간이 -14가 되면 [-14, -5]을 넣는다.
그리고 또 시간이 증가하여 -13이 되었다.
현재 우선순위 큐의 top은 [-18, -13]인데 이 차는 고속도로에서 나가야하므로 -13에서 카메라를 설치한다.
그리고 현재 큐에 있는 차들은 모두 -13에서 카메라를 만날 수 있으므로 큐를 모두 비워준다.
큐가 비워진채로 시간이 또 증가하여 -5가 되면 [-5,-3]을 큐에 넣는다.
시간이 -3이 되면 [-5,-3]을 만나서 카메라를 설치하고 큐를 비운다.
모든 차가 고속도로를 탈출했으므로 최종적으로 설치된 카메라는 두대다.
while (idx < size || !q.empty()) {
while (idx < size && time == routes[idx][0]) { // 차가 고속도로에 진입
q.push(routes[idx][1]); // 해당 차를 큐에 넣는다.
idx++; // 다음 차를 선택하기 위한 인덱스
}
if (!q.empty() && q.top() == time) { // 차가 고속도로에서 나감
while (!q.empty()) { // 큐를 비워준다.
q.pop();
}
answer++; // 카메라 설치
}
time++;
}
디버깅
반례
routes : [[-30000, 30000], [-4000, 4000], [-4000, 4000]]
차가 고속도로에 진입하면 다음 차를 선택했는데, 동일한 시간에 여러대의 차가 고속도로에 진입하는 경우가 있음.
반복문을 이용해서 모든 차가 고속도로에 진입 후 다음 차를 선택하도록 수정
수정 전
if (idx < size && time == routes[idx][0]) {
q.push(routes[idx][1]);
idx++;
}
수정 후
while (idx < size && time == routes[idx][0]) {
q.push(routes[idx][1]);
idx++;
}
구현
// c++
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
int solution(vector<vector<int>> routes) {
int answer = 0;
sort(routes.begin(), routes.end());
priority_queue<int, vector<int>, greater<int>>q;
int idx = 0;
int size = routes.size();
int time = routes[0][0];
while(idx < size || !q.empty()){
while(idx<size && time == routes[idx][0]){
q.push(routes[idx][1]);
idx++;
}
if(!q.empty() && q.top() == time){
while(!q.empty()){
q.pop();
}
answer++;
cout<<time<<endl;
}
time++;
}
return answer;
}
최근댓글