https://school.programmers.co.kr/learn/courses/30/lessons/64062
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
효율성 검사가 있는 문제다
친구들이 하나씩 다리를 건너면서 stones의 값을 하나씩 줄인다면 답은 구할 수 있겠지만 당연히 너무 오랜 시간이 걸릴 것이다.
시간복잡도는 stones의 길이가 n, stones의 각 값의 최대값이 m일 때, O(n*stones*k)가 될 것이다.
대신 답으로부터 역으로 계산해서, 만약 n명의 친구들이 다리를 건널 수 있다고 가정한다면, 써있는 숫자가 n보다 작은 다리가 k번 이상 연속될 경우 이 가정은 틀렸다고 생각할 수 있다.
n을 1부터 200,000까지 증가시키면서 위의 방법을 적용해보면 n을 찾을 수 있다.
그러나 이 방법도 O(n*m*k)로 충분히 빠르게 계산할 수 없다.
이분 탐색 방식을 적용해서 시간을 줄일 수 있다.
기본적으로는 위에서 설명한 방식과 똑같다. 하지만 n을 1부터 200,000까지 하나씩 증가시키는 대신, 이분 탐색을 적용하는 것이다.
min = 0, max = 200,000이라고 하자. mid = (max + min) / 2이다.
n = mid일 때 다리를 건널 수 있다면 min = mid + 1로 바꾸고 다시 계산해본다.
반대로 다리를 건널 수 없다면 max = mid로 바꾸고 다시 계산한다.
이렇게 하면 시간복잡도에서 m을 logm까지 줄일 수 있다.
코드
function solution(stones, k) {
var max = stones.reduce((a, b) => Math.max(a, b));
var min = 0;
var mid = Math.floor((min + max) / 2);
while (min < max) {
// 검사
var count = 0;
var pass = true;
for (var i = 0; i < stones.length; i++) {
if (stones[i] <= mid) {
count++;
if (count === k) {
pass = false;
break;
}
} else {
count = 0;
}
}
if (pass) {
min = mid + 1;
// 건널 수 있음
} else {
max = mid;
// 건널 수 없음
}
var mid = Math.floor((min + max) / 2);
}
return mid;
}'코딩연습' 카테고리의 다른 글
| (C#) 스타 수열 (0) | 2025.07.29 |
|---|---|
| (javascript) 블록 이동하기 (1) | 2025.07.28 |
| (javascript) 기둥과 보 설치 (2) | 2025.07.24 |
| (C#) 등대 (1) | 2025.07.23 |
| (C#) 디스크 컨트롤러 (1) | 2025.07.22 |