내가 개발해볼게!!
[PRO] 프로그래머스 155651번: 호텔 대실(Java) 본문
https://school.programmers.co.kr/learn/courses/30/lessons/155651
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제
호텔을 운영 중인 코니는 최소한의 객실만을 사용하여 예약 손님들을 받으려고 합니다. 한 번 사용한 객실은 퇴실 시간을 기준으로 10분간 청소를 하고 다음 손님들이 사용할 수 있습니다.
예약 시각이 문자열 형태로 담긴 2차원 배열 book_time이 매개변수로 주어질 때, 코니에게 필요한 최소 객실의 수를 return 하는 solution 함수를 완성해주세요.
제한 사항
- 1 ≤ book_time의 길이 ≤ 1,000
- book_time[i]는 ["HH:MM", "HH:MM"]의 형태로 이루어진 배열입니다.
- [대실 시작 시각, 대실 종료 시각] 형태입니다.
- 시각은 HH:MM 형태로 24시간 표기법을 따르며, "00:00"부터 "23:59"까지로 주어집니다.
- 예약 시각이 자정을 넘어가는 경우는 없습니다.
- 시작 시각은 항상 종료 시각보다 빠릅니다.
- book_time[i]는 ["HH:MM", "HH:MM"]의 형태로 이루어진 배열입니다.
입력
출력
난이도
Level 2
Sol
1. 입력받은 String 배열을 int 배열로 변환한다. 이때 퇴실 시각 + 청소 시간 10분을 반영해 값을 조정한다
2. 람다식을 사용해 int 배열을 오름차순으로 정렬한다. 대실 시작 시각을 우선적으로 비교하고, 같다면 대실 종료 시각을 비교한다.
3. 우선순위 큐를 사용해 각 예약을 객실에 배정한다.
- 우선순위 큐 내의 데이터 하나를 객실 하나라고 가정하고, 각 객실의 마지막 퇴실 시각을 저장한다.
- int 배열에 저장된 데이터들을 정렬된 순서대로 객실의 마지막 퇴실 시각과 비교한다.
- 같은 객실에 예약할 수 있다면, 즉 만약 마지막 퇴실 시각과 새 데이터의 시작 시각이 겹치지 않으면 큐에서 기존 데이터를 제거하고 새 데이터의 퇴실 시각을 추가한다.
- 같은 객실에 예약할 수 없다면, 즉 만약 마지막 퇴실 시각과 새 데이터의 시작 시각이 겹치면 기존 데이터 제거 없이 큐에 새 데이터의 퇴실 시각을 추가한다.
4. 모든 객실의 배정을 마치고, 객실의 개수를 최종적으로 반환한다. 여기서 객실의 개수는 우선순위 큐 내에 들어 있는 데이터의 개수와 같다.
class Solution {
public int solution(String[][] book_time) {
// 1. 입력받은 배열을 int 배열로 변환
int[][] times = new int[book_time.length][2];
for (int i = 0; i < book_time.length; i++) {
times[i][0] = Integer.parseInt(book_time[i][0].replace(":", ""));
int e = Integer.parseInt(book_time[i][1].replace(":", "")) + 10; // 퇴실 후 청소 시간 반영
if (e % 100 >= 60) { // 청소 시간 10분을 더했을 때 60분 이상이라면
e = e - 60 + 100; // 60분 빼고 한 시간 추가
}
times[i][1] = e;
}
// 2. 오름차순으로 정렬
Arrays.sort(times, (a, b) -> {
if (a[0] > b[0]) return 1;
else if (a[0] < b[0]) return -1; // 대실 시작 시각을 우선적으로 비교
else {
if (a[1] >= b[1]) return 1; // 시작 시각이 같다면 종료 시각을 비교
else return -1;
}
});
// 3. 각 예약을 객실에 배정
PriorityQueue<Integer> rooms = new PriorityQueue<>();
// 요소를 추가하면 자동으로 오름차순 정렬이 되는 priorityQueue를 사용
// int[]를 추가하려고 했으나 굳이 시작 시각과 종료 시각을 모두 가지고 있을 필요가 없다고 생각해 종료 시각만 저장
// queue에 들어 있는 각 요소들이 객실이라고 생각
for (int[] book : times) {
if (rooms.isEmpty()) { // 첫 예약의 퇴실 시각을 큐에 넣음
rooms.add(book[1]);
} else { // 두 번째 예약부터
int end = rooms.peek(); // 예약된 객실 중 가장 늦은 퇴실 시각을 가져온다
if (end <= book[0]) { // 같은 객실에 예약할 수 있다면
rooms.poll(); // 기존 데이터를 제거하고 (같은 객실로 취급하기 위해)
rooms.add(book[1]); // 새 데이터의 종료 시각을 추가한다.
} else { // 같은 객실에 예약할 수 없다면
rooms.add(book[1]); // 기존 데이터를 제거하지 않고 그 위에 새 데이터의 종료 시각을 추가
}
}
}
return rooms.size();
}
}
😅
람다식 내에서 조건문을 사용할 때 꼭 모든 경우에 대한 분기점을 만들어줘야 한다. if, else if만 사용하고 else를 써주지 않아 에러가 났었다.
'Algorithm > Programmers' 카테고리의 다른 글
[PRO] 프로그래머스 148653번: 마법의 엘리베이터 (0) | 2023.09.19 |
---|