문제 풀이 날짜: 2023.05.05
포스트 작성일: 2023.05.06
* 학습 목적으로 작성하는 글입니다. 풀이가 정석적이지 못할 수도 있습니다.
문제 출처
프로그래머스 코딩테스트 고득점Kit 그리디 편 : 구명보트 (Lv.2) (문제 링크)
키워드
그리디, 투포인터
풀이 접근법
- 보트에는 한 번에 최대 2명씩만 탈 수 있다는 점에 유의하자.
- 입력의 수는 1 ≤ n ≤ 50,000 이므로, 50,000 × 50,000 = 2,500,000,000 으로 10^9 시간을 초과한다. 따라서 O(n²) 시간을 넘지 않는 방식으로 풀이해야 한다.
- 보트의 무게 제한을 넘기지 않으려면 가능한 가벼운 사람과 무거운 사람을 함께 태워 보내야 한다. ⇒ 주어진 인원의 무게를 오름차순으로 정렬해서 양 끝을 탐색한다.
- 배열을 정렬하였으므로 왼쪽 포인터와 오른쪽 포인터가 가리키는 사람을 함께 태울 수 있는지의 여부를 체크한다.
- 만약 두 사람을 함께 태울 수 없다면 맨 오른쪽의 무거운 사람을 먼저 보트 하나에 태워보내고(
right += 1
) 다음 사람들의 무게를 체크한다. - 둘 다 태울 수 있다면 해당 2인을 태우고 양쪽의 인덱스를 모두 증가시킨다. (
left += 1
&right += 1
) - 두 포인터가 만나는 지점까지 탐색하면 종료된다. (같은 사람을 가리키게 되면 종료)
코드
import java.util.*;
class Solution {
public int solution(int[] people, int limit) {
int answer = 0;
Arrays.sort(people);
int left = 0;
int right = people.length - 1;
while(left <= right) {
if(people[left] + people[right] <= limit) {
left += 1;
}
right -= 1;
answer += 1;
}
return answer;
}
}
처음에는 배열을 정렬한 뒤 맨 앞부터 두 명씩 가벼운 사람을 태우는 방식으로 풀었는데 대부분의 테스트 케이스에서 틀렸다. 반례를 찾아보니 인접한 무게의 사람들끼리 태우는 것으로는 해를 구할 수 없어, 투포인터로 바꿔 풀었다.
Git 링크
https://github.com/jinju9553/23-CodingTest/blob/main/week7/day3/Lifeboat.java
'Study > Problem Solving' 카테고리의 다른 글
[백준 / Java] 11659번: 구간 합 구하기 4 (실버3) (0) | 2023.05.18 |
---|---|
[백준 / Java] 13305번: 주유소 (실버3) (0) | 2023.05.18 |
[SWEA / Java] 1208번: Flatten (D3) (0) | 2023.05.18 |
[SWEA / Java] 1206번: View (D3) (0) | 2023.05.18 |
[프로그래머스 / Java] 베스트앨범(Lv.3) (0) | 2023.05.06 |