[프로그래머스/js] 구명보트 (탐욕법)

이다형·2023년 10월 18일
0

문제 설명

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.

예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.

구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.

사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.

단순히 맨 앞 원소부터 일일히 모든 원소와 더해보며 할 수도 있겠지만
수가 커지면 너무 오래 걸리게 되어 통과할 수 없다.

다음과 같은 방법을 사용하면 최소 시간에 해결할 수 있다.

function solution(people, limit) {
    let count = 0;
    people.sort((a,b)=>b-a);
    
    for( let i = 0, j = people.length - 1; i <= j; i++){
        if(people[i] + people[j] <= limit) 
            j--
        count ++
    }
 
    return count
}

우선 people을 내림차순 정렬한다.
[70, 50, 80, 50] => [70, 80, 50, 50]

i = 0 부터
j=people.length -1 , people의 제일 끝 원소부터 시작한다.

제일 무거운 사람 people[i] 부터 제일 가벼운 사람 people[j] 과 붙인다.
그 무게가 limit를 초과한다면 제일 가벼운 사람은 그대로 두고 count를 하나 올린다.

그 다음 무거운 사람 people[i+1]과 제일 가벼운 사람 people[j] 을 붙인다.
그무게가 limit 이하라면 제일 가벼운 사람도 같이 나갈 수 있으므로 count를 하나 올리고
n의 수를 하나 줄여 다음 비교부터는 두번째로 가벼운 사람과 붙일 수 있도록 한다.

그 다음 부터는 people[i+2] 와 people[j-1], people[i+3]과 people[j-2] ...
을 반복하다 i가 j보다 커지는 순간 반복을 종료하고 count를 리턴한다.

0개의 댓글