[프로그래머스] Lv.2 구명보트 - JavaScript

윤지·2024년 11월 23일

코딩테스트

목록 보기
6/10
post-thumbnail

📍 문제

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

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

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

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

제한사항

  • 무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다.
  • 각 사람의 몸무게는 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없습니다.

입출력 예

peoplelimitreturn
[70, 50, 80, 50]1003
[70, 80, 50]1003

🥔 내 코드

function solution(people, limit) {
    // 무게 순으로 내림차순 정렬
    const peoples = people.sort((a, b) => b - a);

    let boat = 0;
    let i = 0; // 가장 무거운 사람
    let j = peoples.length - 1; // 가장 가벼운 사람
    console.log(i, j)

    while (i <= j) {
        if (peoples[i] + peoples[j] <= limit) {
            // 가장 가벼운 사람과 가장 무거운 사람 같이 탑승
            j--;
        }
        // 혼자 탑승
        i++;
        boat++;
    }

    return boat;
}

✅ 풀이 과정

1. 배열 정렬

  • 사람들의 몸무게 배열을 내림차순으로 정렬(무거운 사람부터 시작)

2. 포인터 설정

  • i: 배열의 시작(가장 무거운 사람)부터 시작
  • j: 배열의 끝(가장 가벼운 사람)부터 시작
  1. 보트 탑승 로직
  • 반복문 (while (i <= j)):
    • ij가 교차할 때까지, 즉 모든 사람을 처리할 때까지 진행
    • 조건: i <= j는 가장 무거운 사람의 인덱스 i가 가장 가벼운 사람의 인덱스 j보다 크거나 같을 때를 의미. 즉, 아직 처리되지 않은 사람이 남아 있는 동안 반복문 실행
  • 조건 확인 (if (peoples[i] + peoples[j] <= limit)):
    • peoples[i]는 가장 무거운 사람의 몸무게, peoples[j]는 가장 가벼운 사람의 몸무게
    • 두 사람의 몸무게 합이 구명보트의 제한 무게를 초과하지 않는지 확인
      • 제한 무게 초과하지 않을 시 두 사람을 같은 보트에 탑승
      • 이 경우 j--로 가장 가벼운 사람을 보트에 태운 후 다음 가벼운 사람을 지정
    • 제한 무게 초과 시 가장 무거운 사람은 혼자 탑승. 이 경우 i++로 무거운 사람을 보트에 태운 후 다음 무거운 사람을 지정
  • 보트 사용:
    • 무거운 사람을 무조건 한 번은 보트에 태우므로 i++ 항상 실행
    • 보트를 사용했으므로 보트 변수에 1 추가

5. 결과 반환

  • 필요한 최소 보트 개수(boat) 반환

💡 다른 사람의 코드


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

풀이

  • 내림차순 정렬 - 가장 무거운 사람부터 차례로 태우기 위해 정렬
  • 포인터 설정
    • i: 가장 무거운 사람부터 시작 (앞)
    • j: 가장 가벼운 사람부터 시작 (뒤)
  • 보트 탑승 로직
    • 무거운 사람 + 가벼운 사람 ≤ limit: 두 명 함께 탑승 (j--)
    • limit 초과: 무거운 사람 혼자 탑승
    • 매 경우 i++ 하여 다음 무거운 사람으로 이동
  • 종료 조건 - i가 j보다 커질 때까지 반복 (모든 사람 탑승 완료)

💬 마치며

기본 for문만 써 왔는데 for문 활용법을 새롭게 알게 됐다. for문에서 두 변수를 동시에 선언하고 조건문으로 활용할 생각은 안 해 봤는데 써먹어 봐야지…✏️

그리고 변수를 따로 선언하지 않고 var로 호이스팅 처리한 점과, 보트 변수를 별도로 만들지 않고 전체 사람 수에서 매칭된 가벼운 사람 수를 빼서 결과를 낸 방식도 좀 신기했다.

profile
프론트엔드 공부 기록 아카이빙🍁

0개의 댓글