본문 바로가기
프로그래밍/알고리즘 문제풀이

[pg] 프로그래머스 호텔 대실

by 노잼인간이라불립니다 2023. 8. 24.

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