[프로그래머스] 디스크 컨트롤러
정렬, 우선순위 큐
이 문제는 디스크를 “대기 시간이 가장 적도록” 우선순위를 배치하여 실행시키는 문제이다.
대기 시간이 가장 적으려면 매 초, 매 순간 정렬을 통해 가장 먼저 끝낼 수 있는 태스크를 빨리 끝내는게 관건이다. 그러나 매 순간 정렬을 한다는 것은 시간적으로 비효율적이다.
따라서 가장 먼저 끝날 수 있는 태스크, 즉 runtime이 가장 적은 태스크를 key로 하는 우선순위 큐(min-heap)을 사용하면 쉽게 구현할 수 있다.
알고리즘은 다음과 같다.
- 작업(jobs 배열)을 시작 시간 기준으로 정렬(내림차순). → deque를 import 하지 않고 list의 pop 메서드를 사용하기 위해 역순으로 정렬했다.
- heap, jobs가 빌 때까지 반복한다.
- 만약 heap만 비어있다면 1초 증가하고 2로 돌아감
- heap에서 하나 pop 하고 현재 시간에 해당 작업의 runtime을 더한다.
- 총 대기 시간에 해당 작업이 기다린 시간을 더한다.(현재 시간 + 요청 시간)
- 작업의 개수대로 나누어 반환
구현
import heapq
def solution(jobs):
jobs.sort(reverse=True)
job_cnt = len(jobs)
cur_time = 0
heap = []
# 시작 시간 초기화
answer = 0
while True:
# 시간에 맞게 들어오는 요청을 모두 heap 에 넣는다.
while True:
if jobs and jobs[-1][0] <= cur_time:
req_time, runtime = jobs.pop()
heapq.heappush(heap, (runtime, req_time))
continue
break
# 반복문 탈출 조건
if not heap:
if not jobs:
break
cur_time += 1
continue
# heap 에서 원소 하나 빼서 일을 진행한다
runtime, req_time = heapq.heappop(heap)
cur_time += runtime
answer += (cur_time - req_time)
return answer // job_cnt
print(solution([[0, 3], [1, 9], [2, 6]]))
print(solution([[1, 3], [2, 3]]))
print(solution([[8, 3], [0, 10], [0, 14]]))