[프로그래머스 level3] 입국심사 javascript

IT공부중·2020년 4월 27일
8

알고리즘

목록 보기
17/49
post-custom-banner

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;
}
profile
4년차 프론트엔드 개발자 문건우입니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2020년 10월 31일

이해가기 쉽게 설명 해주셔서 감사합니다 :)

답글 달기