[프로그래머스] 구명보트 문제풀이 (Java)

ajufresh·2020년 5월 26일
2

프로그래머스

목록 보기
1/14
post-custom-banner

🔗 링크

https://programmers.co.kr/learn/courses/30/lessons/42885


🛶 문제

두 명씩 옮길 수 있는 구명보트가 있다.

구명보트는 무게에 한계가 있고, (limit)

사람들을 옮기는 최소한의 횟수를 구해야한다.

👀 예제로 문제 파악하기

입력 : people [70, 50, 80, 50], limit 100

최소한의 횟수로 옮기기 위해서는 가장 몸무게가 큰 사람 + 가장 몸무게가 작은 사람 조합이여야 한다.

위 예제같은 경우에는

  1. 80 (최솟값인 50과 같이 가면 한계점인 100을 넘는다.)
  2. 70 (최솟값인 50과 같이 가면 한계점인 100을 넘는다.)
  3. 50 + 50

순으로, 총 횟수인 3을 return한다.


입력 : people 50, 30, 20, 70, 10, limit 100

  1. 70 + 10
  2. 50 + 20
  3. 30

😮 알고리즘 풀이 순서


max는 정렬된 배열의 맨 끝에서, min은 맨 처음에서 시작.

max + min이 limit을 넘으면 혼자 가는 것으로, 넘지 않으면 두 개가 함께 가는 것으로 처리

50 + 80은 limit인 100을 넘으니 80 혼자 간다.


50 + 70도 마찬가지

50 + 50은 limit인 100과 같으므로 둘이 갈 수 있음

둘이 간다는 차리를 하기 위해 min을 1 누적해준다.


  1. 배열 people을 정렬한다.

  2. min은 0으로 초기화해준다.

    • 최솟값의 위치의 역할
  3. 반복문을 돈다.

    • 초기값 max는 people 배열의 크기 -1
      - max는 최댓값 위치의 역할
    • min ≤ max일 때까지 반복
      - 최솟값의 위치가 최댓값의 위치보다 커지면 반복 종료
    • max—
  4. 반복문

    • people의 min 위치에 있는 값 + max 위치에 있는 값이 limit보다 작거나 같으면 min++.
    • answer++
      - 위 if문에서 걸리지 않으면 현재 최댓값 혼자 구명보트를 탄 걸로 처리

👨‍💻 코드

public class Solution {

  public int solution(int[] people, int limit) {
    int answer = 0;

    Arrays.sort(people);

    int min = 0;

    for (int max = people.length - 1; min <= max; max--){
      if (people[min] + people[max] <= limit) min++;
      answer++;
    }

    return answer;
}

  @Test
  public void 정답() {
    Assert.assertEquals(1, solution(new int[]{50}, 50));
    Assert.assertEquals(2, solution(new int[]{20, 50, 50, 80}, 100));
    Assert.assertEquals(3, solution(new int[]{70, 50, 80, 50}, 100));
    Assert.assertEquals(3, solution(new int[]{50, 30, 20, 70, 10}, 100));
    Assert.assertEquals(3, solution(new int[]{70, 80, 50}, 100));
    Assert.assertEquals(5, solution(new int[]{10, 20, 30, 40, 50, 60, 70, 80, 90}, 100));
  }
}
profile
공블로그
post-custom-banner

1개의 댓글

comment-user-thumbnail
2020년 10월 21일

안녕하세요. 포스팅 잘 봤습니다. 질문이 하나 있는데요.

위 코드에서는 max와 같이 보트를 탈 짝으로 바로 min을 지정하여 max+min <= limit을 검사합니다.

제가 이해가 안 되는 것은 "왜 max의 짝을 바로 min으로 잡아도 되는것인가?"입니다.

만약 min보다 더 큰 값 n이 있고 n + max <= limit이라면.. (max, n)을 태워서 보내고 min은 나중을 위하여 아껴놓는게 맞는 것 아닌가 싶어서요.

min, A, B, max로 오름차순 정렬 되어있을 경우
(max, B)검사 -> (max, A)검사 -> (max, min)검사
이런식으로 검사하면서 (max,B) <= limit이라면 (max, B)를 먼저 보내는게 min을 아낄 수 있는 방법이 아닌가요?

왜 B, A를 건너뛰고 바로 (max, min)을 검사해도 되는 것인지 궁금합니다.

답글 달기