이분탐색을 완벽하게 이해하고 넘어가겠다는 항해99의 공부 방식에 맞춰 오늘도 이분탐색을 시작해보려고 한다...
근데 사실 아직 다 이해 못한거같기도.. mid가 뭘 의미하는지를 찾는게 가장 어려워...
n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다.
처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한 명만 심사를 할 수 있습니다. 가장 앞에 서 있는 사람은 비어 있는 심사대로 가서 심사를 받을 수 있습니다. 하지만 더 빨리 끝나는 심사대가 있으면 기다렸다가 그곳으로 가서 심사를 받을 수도 있습니다.
모든 사람이 심사를 받는데 걸리는 시간을 최소로 하고 싶습니다.
입국심사를 기다리는 사람 수 n, 각 심사관이 한 명을 심사하는데 걸리는 시간이 담긴 배열 times가 매개변수로 주어질 때, 모든 사람이 심사를 받는데 걸리는 시간의 최솟값을 return 하도록 solution 함수를 작성해주세요.
[제한사항]
입국심사를 기다리는 사람은 1명 이상 1,000,000,000명 이하입니다.
각 심사관이 한 명을 심사하는데 걸리는 시간은 1분 이상 1,000,000,000분 이하입니다.
심사관은 1명 이상 100,000명 이하입니다.
def solution(n, times):
# 시작 시간과 끝 시간을 설정
start = 1
end = max(times) * n
answer = end # 최악의 경우 시간을 초기 답안으로 설정해둠
while start <= end:
# 현재 예상 최소 시간
mid = (start + end) // 2
# mid 시간 동안 심사할 수 있는 총 인원 수
people_checked = sum(mid // time for time in times)
if people_checked >= n:
# 충분한 인원을 처리할 수 있으면 시간을 줄여서 더 최적의 값을 찾음
answer = mid
end = mid - 1
else:
# 인원을 처리할 수 없다면 시간을 늘려야 함
start = mid + 1
return answer
이분 탐색을 오늘까지 3개의 문제를 풀어보면서 mid를 찾는 것이 가장 어렵다는 것을 느낄 수 있었다.
그래서 문제를 통해서 mid가 무엇을 의미하는지를 찾는 방법에 대해서 조금 생각을 해보았다.
1. 문제에서 "최소값"이나 "최대값"을 찾는 요구 확인하기
이분 탐색 문제는 보통 특정 범위 내에서 최소 혹은 최대값을 찾으라는 요구가 있다.
예를 들어, 이 문제에서는 모든 사람이 심사를 받을 수 있는 최소 시간을 찾는 것이 목표이다.2. mid가 어떤 값의 "최대/최소"를 나타내는지 정의하기
mid는 시작과 끝의 중간값으로, 가능한 후보 시간 값입니다.
문제를 풀기 위한 특정 시간 범위를 설정한 후, mid는 이 시간 범위의 중간값으로 간주되어 해당 시간 내에 작업을 완료할 수 있는지를 판단하는 기준이 된다.3. mid의 의미를 찾기 위한 질문들
mid가 특정 시간이라면, "이 시간 내에 모든 사람을 처리할 수 있는가?" 같은 질문을 던져 볼 수 있다.
이 질문을 통해 mid가 "최소 시간"이라는 의미를 가지며, 이 시간을 만족하도록 각 심사관이 처리할 수 있는지 계산하게 된다.4. mid와 목표 비교하는 조건식 작성
이 문제에서는 mid 시간 동안 각 심사관이 몇 명을 처리할 수 있는지 확인한 후, 그 합이 총 인원보다 크거나 같은지를 확인한다.
이렇게 mid의 의미를 계산하는 기준으로 만들면, start, end 값을 조정해 범위를 좁혀가며 목표에 도달할 수 있다.
이분 탐색을 3일째 공부하면서, 이분 탐색의 방식에 대해서 조금씩 익숙해져가고 있는 것 같다. 일단 문제를 확인할 때 해석하면서 이분탐색을 활용해야한다는 것을 일차적으로 내가 먼저 결정할 수 있다는 점에서 성장하고 있다고 생각한다.
이분 탐색에 대해서 더 공부하고 좀더 복잡한 문제를 만나도 쉽게 해결해내고 싶다는 생각이 들었다.