[프로그래머스] 호텔 방 배정 / Python / 재귀함수

이다혜·2021년 7월 21일
0
post-custom-banner

호텔 방 배정

문제

전체 방 개수 k와 고객들이 원하는 방 번호가 순서대로 들어있는 배열 room_number가 매개변수로 주어질 때, 각 고객에게 배정되는 방 번호를 순서대로 배열에 담아 return 하도록 solution 함수를 완성해주세요.
고객에게 방을 배정할 때는 다음과 같은 규칙을 따릅니다.

1. 한 번에 한 명씩 신청한 순서대로 방을 배정합니다.
2. 고객은 투숙하기 원하는 방 번호를 제출합니다.
3. 고객이 원하는 방이 비어 있다면 즉시 배정합니다.
4. 고객이 원하는 방이 이미 배정되어 있으면 원하는 방보다 번호가 			
크면서 비어있는 방 중 가장 번호가 작은 방을 배정합니다.
  • 입출력 예시
kroom_numberresult
10[1, 3, 4, 1, 3, 1][1, 3, 4, 2, 5, 6]

첫 번째 ~ 세 번째 고객까지는 원하는 방이 비어 있으므로 즉시 배정받을 수 있습니다. 네 번째 고객의 경우 1번 방을 배정받기를 원했는데, 1번 방은 빈 방이 아니므로, 1번 보다 번호가 크고 비어 있는 방 중에서 가장 번호가 작은 방을 배정해야 합니다. 1번 보다 번호가 크면서 비어있는 방은 [2번, 5번, 6번...] 방이며, 이중 가장 번호가 작은 방은 2번 방입니다. 따라서 네 번째 고객은 2번 방을 배정받습니다. 마찬가지로 5, 6번째 고객은 각각 5번, 6번 방을 배정받게 됩니다.

  • 제한사항
    - k는 1 이상 1012 이하인 자연수입니다.
    - room_number 배열의 크기는 1 이상 200,000 이하입니다.
    - room_number 배열 각 원소들의 값은 1 이상 k 이하인 자연수입니다.
    - room_number 배열은 모든 고객이 방을 배정받을 수 있는 경우만 입력으로 주어집니다.
    • 예를 들어, k = 5, room_number = [5, 5] 와 같은 경우는 방을 배정받지 못하는 고객이 발생하므로 이런 경우는 입력으로 주어지지 않습니다.

나의 풀이 1

정확성 100% 효율성 0%
원하는 방이 비어있는지 아닌지 O(1) 시간으로 파악하기 위해 dictionary 사용
하지만 빈 방 중 다음 큰 방을 찾기 위해 방 번호를 차례로 증가시키면서 계속 탐색하는 과정에서 시간이 매우 많이 걸린다.

def solution(k, room_number):
    full = {}
    answer = []
    for r in room_number:
        # 원하는 방이 비어있다면 즉시 배정
        if r not in full:
            full[r] = 1
            answer.append(r)
        # 이미 배정된 방이면
        else:
            # 원하는 방보다 번호가 크면서 비어있는 방 중 가장 번호가 작은 방 배정
            while True:
                r += 1
                if r not in full:
                    full[r] = 1
                    answer.append(r)
                    break
            
    return answer

나의 풀이 2

재귀함수를 쓰자!
방을 배정할 때마다 배정된 방보다 번호가 크면서 비어있는 방 중 가장 번호가 작은 방을 가리키도록 'key:value = 배정된 방:빈 방 중 다음 큰 방'으로 dictionary 업데이트

import sys
sys.setrecursionlimit(1000000)

def find_min_empty_room(r, full):
    # 원하는 방이 비어있으면
    if r not in full:
        # 배정된 방보다 번호가 크면서 비어있는 방 중 가장 번호가 작은 방을 가리키도록 저장
        full[r] = r + 1
        return r
    # 이미 배정된 방이면
    else:
        # 배정할 새로운 방을 찾음
        nr = find_min_empty_room(full[r], full)
        # 배정된 방보다 번호가 크면서 비어있는 방 중 가장 번호가 작은 방을 가리키도록 저장
        full[r] = nr + 1
        return nr

def solution(k, room_number):
    full = {}
    answer = []
    for r in room_number:
        answer.append(find_min_empty_room(r, full))
    return answer
profile
하루하루 성장중
post-custom-banner

0개의 댓글