본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.
카카오 초등학교의 니니즈 친구들이 라이언 선생님과 함께 가을 소풍을 가는 중에 징검다리가 있는 개울을 만나서 건너편으로 건너려고 합니다. 라이언 선생님은 니니즈 친구들이 무사히 징검다리를 건널 수 있도록 다음과 같이 규칙을 만들었습니다.
니니즈 친구들은 개울의 왼쪽에 있으며, 개울의 오른쪽 건너편에 도착해야 징검다리를 건넌 것으로 인정합니다.
니니즈 친구들은 한 번에 한 명씩 징검다리를 건너야 하며, 한 친구가 징검다리를 모두 건넌 후에 그 다음 친구가 건너기 시작합니다.
디딤돌에 적힌 숫자가 순서대로 담긴 배열 stones와 한 번에 건너뛸 수 있는 디딤돌의 최대 칸수 k가 매개변수로 주어질 때, 최대 몇 명까지 징검다리를 건널 수 있는지 return 하도록 solution 함수를 완성해주세요.
stones | k | result |
---|---|---|
[2, 4, 5, 3, 2, 1, 4, 2, 5, 1] | 3 | 3 |
count
를 기준으로 이분 탐색을 진행한다.count
만큼 니니즈가 건넜을 때가 유효한지 available()
에서 검사한다.k
번 이상 나온 경우 false, 그 외의 경우 true를 리턴하고 답을 갱신한다.검색 없이 내 힘으로 풀어낸 첫 번째 level 2 문제다!! 정말 기쁘다!!
위의 이분 탐색 로직은 곧잘 적었는데 available()
에서 기준을 음수로 안 잡고 0 이하로 두는 바람에 잠깐 삽질을 했다. 해당 count
의 니니즈까지 건넌 후에 0이 된 것이므로 0일 때 jumpCount
를 증가시키면 안 되는데 조건을 잘못 걸어 놨던 것이다.
또, available()
에서 일일히 jumpCount
를 체크하지 않는 더 효율적인 방법은 없을까 생각을 해보았는데 떠오르지 않아서 일단은 이렇게 작성하였고, 다른 더 좋은 방법이 있나 프로그래머스 다른 사람의 풀이를 쓱 봤는데 보이지 않았다. 나중에 실력이 늘어서 좋은 풀이가 생각이 나면 고쳐야겠다.
import java.util.*;
class Solution {
private static final int MIN_COUNT = 0;
private static final int MAX_COUNT = 200000000;
public int solution(int[] stones, int k) {
int left = MIN_COUNT;
int right = MAX_COUNT;
int answer = 0;
while (left <= right) {
int mid = (left + right) / 2;
if (available(mid, stones, k)) {
answer = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
return answer;
}
private boolean available(int count, int[] stones, int k) {
int jumpCount = 0;
for (int i = 0; i < stones.length && jumpCount < k; i++)
if (stones[i] - count < 0) jumpCount++;
else jumpCount = 0;
return jumpCount < k;
}
}