https://programmers.co.kr/learn/courses/30/lessons/42627
이분탐색으로 분류되어 있는 문제이다.
입력으로 들어오는 n명을 검사하는데 몇분이 걸리는지를 체크하면 된다.
심사관은 한 사람당 times의 배열의 값만큼 검사시간이 걸린다.
처음에 검사시간이 작은 심사관부터 계산하기 위해 오름차순으로 정렬을 해준다. 그냥 sort를 사용해도 되지만 그렇게 하면 문자열 순서대로 정렬을 하기 때문에
(a, b) => a - b;
라는 함수를 넣어주면 숫자 순서대로 정렬이 된다. 내림차순으로 정렬을 하기 위해서는
(a, b) => b - a;
라는 함수를 넣어주면 된다.
left에는 최소로 걸릴 시간, right에는 최대로 걸릴 시간을 넣어주었다. right의 값은 최고 오래 걸리는 사람이 n명을 다 검사했을 때의 값이다.
이분 탐색을 시작한다. mid 값은 left + right 한 값은 중앙값이다. times 만큼 반복문을 도는데 mid 값을 각각의 시간으로 나눴을 때가 해당 심사관이 검사할 수 있는 사람 수이다.
모든 사람이 심사를 받는데 걸리는 시간의 최솟값을 구하는 것이기 때문에 이 값이 n명을 검사하는 값을 넘으면 그 값과 answer 값 중 작은 값을 answer에 저장한다.
만약 count 값이 n 보다 많거나 크면 시간을 더 줄이기 위해 mid 값을 더 낮춰도 된다는 뜻이므로 right = mid - 1; 을 수행해주고
count 값이 n보다 작으면 mid 값을 더 높여야 된다는 뜻이므로 left = mid + 1; 을 해준다.
그렇게 모두 돌아서 마지막 최솟값이 answer이다.
function solution(n, times) {
times.sort((a,b) => a-b);
let left = 1;
let right = n * times[times.length -1];
let answer = right; // 최대값.
while(left <= right){
let mid = Math.floor((left + right) / 2);
let count = 0
times.forEach(value => {
count += Math.floor(mid / value); // 한 사람당 몇명 할 수 있는지
if(count >= n) {
answer = Math.min(mid, answer); // 최솟값
return;
};
});
if (count >= n) {
right = mid - 1;
}
else {
left = mid + 1;
}
}
return answer;
}
이해가기 쉽게 설명 해주셔서 감사합니다 :)