3 분 소요

마흔 두 번째 포스팅

안녕하세요! 마흔 두 번째 포스팅으로 찾아뵙게 되어 반갑습니다!♥

오늘의 포스팅 내용은 프로그래머스 - 호텔 대실에 관한 내용입니다.
자세한 내용을 알아보러 갑시다❗️

[Boongranii] Here We Go 🔥


1️⃣ 문제

[프로그래머스] 호텔 대실 (문제 링크)

💨 문제 설명

호텔을 운영 중인 코니는 최소한의 객실만을 사용하여 예약 손님들을 받으려고 합니다. 한 번 사용한 객실은 퇴실 시간을 기준으로 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 result
[[“15:00”, “17:00”], [“16:40”, “18:20”], [“14:20”, “15:20”], [“14:10”, “19:20”], [“18:20”, “21:20”]] 3
[[“09:10”, “10:10”], [“10:20”, “12:20”]] 1
[[“10:20”, “12:30”], [“10:20”, “12:30”], [“10:20”, “12:30”]] 3

💨 입출력 예 설명

입출력 예 #1

image

위 사진과 같습니다.

입출력 예 #2

첫 번째 손님이 10시 10분에 퇴실 후 10분간 청소한 뒤 두 번째 손님이 10시 20분에 입실하여 사용할 수 있으므로 방은 1개만 필요합니다.

입출력 예 #3

세 손님 모두 동일한 시간대를 예약했기 때문에 3개의 방이 필요합니다.


2️⃣ 문제 풀이

🔥 나의 문제 풀이

  1. 배열을 오름차순으로 정렬함.
  2. 계산의 편의성을 위해서 시간을 분으로 변경함(10분 청소 시간까지 추가해줌.)
  3. 이제 예약 처리 과정을 진행
  4. 예약 가능한 방이 있는지 확인하기 위해 isContinue 변수 사용.
  5. 내부 반복문에서는 현재 예약 요청의 시작 시간과 각 방의 종료 시간을 비교하여 예약 가능한 방을 찾음.
  6. 예약 가능한 방이 있다면 해당 방에 예약을 할당하고 isContinue 변수를 true로 설정한 후 내부 반복문 종료.
  7. 예약 가능한 방이 없다면 isContinue 변수는 false이므로 새로운 방을 추가함.
  8. 예약 가능한 방이 있는지 확인하는 과정을 모든 예약 요청에 대해 반복함.
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
function solution(book_time) {
  const room = [];
  const arr = [];
  const bookingTime = book_time.sort();

  // 시간을 분으로 변환
  for (let i = 0; i < bookingTime.length; i++) {
    let [startHour, startMin] = bookingTime[i][0].split(":");
    let [endHour, endMin] = bookingTime[i][1].split(":");
    let startTime = parseInt(startHour) * 60 + parseInt(startMin);
    let endTime = parseInt(endHour) * 60 + (parseInt(endMin) + 10);

    arr.push([startTime, endTime]);
  }
  // console.log(arr)
  // [
  //   [ 850, 1170 ],
  //   [ 860, 930 ],
  //   [ 900, 1030 ],
  //   [ 1000, 1110 ],
  //   [ 1100, 1290 ]
  // ]

  // 예약 처리 과정
  for (let i = 0; i < arr.length; i++) {
    let isContinue = false;

    for (let j = 0; j < room.length; j++) {
      if (arr[i][0] >= room[j][1]) {
        isContinue = true;
        room[j] = arr[i];
        break;
      }
    }
    if (!isContinue) {
      room.push(arr[i]);
    }
  }

  return room.length;
}

console.log(
  solution([
    ["14:10", "19:20"],
    ["14:20", "15:20"],
    ["15:00", "17:00"],
    ["16:40", "18:20"],
    ["18:20", "21:20"],
  ])
);

예약 처리 과정이 꽤나 까다로웠다. 일단 주어진 배열을 오름차순으로 정렬하면 문제 풀기 수월할 것이라고 생각했다.

그 후 시간을 분으로 변환하였다. 그래야 예약 처리 과정에서 비교하기가 편하기 때문이다. 또한, 뭐 테스트 케이스에서 통과되지 않는 케이스도 있었겠지. 어쨌든 그 위기는 모면했다.

주어진 배열을 순회하며 예약된 방에 넣을 지 말 지를 판단해야 한다. 이것은 현재 예약 요청 시작 시간과 각 방의 종료 시간을 비교하면 됐다.

현재 요청한 시작 시간이 방의 종료 시간보다 뒤에 시간이면(즉, 크거나 같으면) 예약을 처리할 수 있으며 그 방 위치에 덮어쓰기를 해주면 된다.

이게 말로는 이해가 안갈 수도 있다. 이것을 보는 독자라면 반복문을 직접 그려보면 이해가 될 것이다. 이러면 안되나? 아니다, 직접 해 보아야 한다.

결론은 그렇게 해서 방의 배열의 길이를 리턴하면 총 몇 개의 방이 필요한 지를 알 수 있다.


3️⃣ 느낀점

생각만 잘 한다면 금방 풀 수 있는 문제일 것이다. 하지만, 난 아니다. 어려웠다. 예약 처리 과정에서 꽤나 생각을 했다. 어떻게 하면 최소의 방을 유지할 수 있을까.. 하며,,

근데 주어진 문제라 최소의 방이지만 생각을 해보니 실제로는 좀 끔찍할 것 같다. 아무도 사용하지 않았던 방을 들어가는 것이 청결하고 공기도 좋을 것이다. 뭐라는거야. 너무 현실적이었네

자, 그럼 이만🐙

댓글남기기