1. 문제 정의
이차원 배열로 각 고객들이 호텔에 입실한 시간과 퇴실한 시간들이 주어진다. ex) [[10:00, 12:00], [11:00, 12:00]]
퇴실시 청소시간은 10분이 걸리며 이후에 방을 다시 고객에게 제공 가능하다. 위와 같은 배열이 주어질 때 가장 최소한의 방을 사용하여 고객에게 방을 제공한다고 했을 때 그 값을 구하는 것.
2. 내가 한 시도
문제를 봤을 때 이전에 풀었던 요격시스템 문제와 비슷하다고 생각했다. 대신에 다른 점이 있다면 이전에는 그냥 숫자로 풀었다면 지금은 문자열 + 시간계산이 들어갔다는 정도이다.
처음에는 문자열을 아예 시간으로 바꾼 다음에 정렬을 해서 풀려고 했지만, 문자열을 이용해서 정렬하고, 나중에 퇴실시간만 시간계산하는 것이 좀 더 코드가 간결하고 간단할 것 같아서 중간에 로직을 변경했다.
시간 계산은 LocalTime클래스에서 다양한 기능들을 제공해주기 때문에 그것들을 이용하였고, 정렬은 Comparator를 이용하여 문자열을 비교 후 정렬하였다. 또한 투포인터로 입실시간과 퇴실시간을 모두 신경쓰지 않게 하기 위해서 하나는 배열 하나는 우선순위 큐를 생성하여 배열 하나에만 집중하면서 큐에서 데이터를 꺼내면서 데이터를 비교할 수 있도록 작성했다.
3. 코드
package al.example.cote.programmers.LV2.호텔대실;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* 프로그래머스 LV2
* 호텔대실
* 접근 방법: 먼저 원본데이터를 입실 시간 기준으로 정렬해놓고, 퇴실시간 기준으로 정렬한 데이터를 우선순위큐에 넣는다.
* 그리고 입실시간 기준 정렬된 데이터를 순회하면서, 퇴실 시간을 체크해가면서 카운트를 적립.
*/
public class Solution {
public static void main(String[] args) {
int solution = solution(new String[][]{{"09:10", "10:10"}, {"10:20", "12:20"}});
System.out.println(solution);
}
public static int solution(String[][] book_time) {
Room roomManager = new Room(); // 방 사용 현황을 관리할 매니저
Arrays.sort(book_time, Comparator.comparing(o -> o[0])); // 입실시간 기준 정렬
PriorityQueue<String> queue = new PriorityQueue<>(Comparator.comparing(o -> o)); // 퇴실 시간 기준 정렬
for (int i = 0; i < book_time.length; i++) {
queue.offer(book_time[i][1]); // 큐에 데이터 삽입
}
/*
* 입실 시간 기준 정렬된 데이터를 순회하면서 퇴실시간과 비교해가면서 카운트를 적립.
*/
for (int i = 0; i < book_time.length; i++) {
String checkinTime = book_time[i][0]; // 입실시간
// 퇴실
while (checkinTime.compareTo(plus10Minute(queue.peek())) >= 0){
roomManager.checkout();
queue.poll();
}
roomManager.checkin(); // 퇴실이 완료된 이후 입실
}
return roomManager.getMaxUsedRoom();
}
public static String plus10Minute(String time){
String[] split = time.split(":");
LocalTime localTime = LocalTime.of(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
return localTime.plusMinutes(10).toString();
}
static class Room{
/**
* 사용중인 방 갯수
*/
private int usingRoom;
/**
* 지금 가지 최대 사용한 방 갯수
*/
private int maxUsedRoom;
public Room() {
this.usingRoom = 0;
this.maxUsedRoom = 0;
}
public void checkin() {
usingRoom++;
if(maxUsedRoom < usingRoom){
maxUsedRoom = usingRoom;
}
}
public void checkout(){
usingRoom--;
}
public int getMaxUsedRoom() {
return maxUsedRoom;
}
}
}
4. 회고
이번 문제는 쉬운듯 보였지만, 문자열 + 정렬 + 시간계산이 포함되어 있어서 조금 까다롭게 느껴졌던 것 같다. 문자열과 정렬, 그리고 시간을 잘 다룰 수 있도록 조금 더 연습이 필요해 보인다.
참조
https://school.programmers.co.kr/learn/courses/30/lessons/155651
'프로그래밍 > 알고리즘 문제풀이' 카테고리의 다른 글
[pg] 프로그래머스 과제 진행하기 (0) | 2023.08.26 |
---|---|
[pg] 프로그래머스 연속된 부분 수열의 합 (0) | 2023.08.25 |
[pg] 프로그래머스 무인도 여행 (2) | 2023.08.24 |
[pg] 프로그래머스 두 원사이의 정수 쌍 (0) | 2023.08.09 |
[pg] 프로그래머스 요격시스템 (0) | 2023.08.09 |