이분 탐색을 활용한 파라메트릭 서치(Parametric Search)를 이용하여 풀었다.
최댓값, 최솟값 등을 찾는 최적화 문제를 결정 문제로 바꾸어 푸는 방법이다.
결정 문제로 바꾸었을 때 장점은 탐색 공간을 줄일 수 있다는 것이다. 예를 들어, k명의 사람이 징검다리를 건널 수없다고 가정해보자. 그렇다면 k+1명의 사람도 건널 수 없으므로 1 ~ k-1까지의 숫자 중에서 건널 수 있는 사람의 최대 수를 찾으면 된다.
보통 이분 탐색을 이용해 탐색 공간을 줄이며 탐색할 때마다 True or False인지 판별하여 정답을 구하게 된다.
# Pseudo-code
while left <= right:
mid = (left + right) // 2
if check(mid): # mid가 문제에서 주어진 조건을 만족하는지 check!
result = mid
left = mid + 1
else:
right = mid - 1
최적화 문제를 결정 문제로 바꾼다고 해서 꼭 더 빠르다는 것은 아니다. True or False 인지를 판별하는 함수의 시간복잡도가 느리다면 결국 바꿔서 풀어도 더 느릴 수 밖에 없다.
예를 들어 최적화 문제로 풀었을 때 시간복잡도가 이라고 하고 True or False 인지를 판별하는 함수 또한 이라고 해보자. 여기에 이분 탐색의 시간 복잡도를 곱해주어야하기 때문에 결과적으로 결정 문제로 풀었을 때 시간 복잡도가 더 커지게 된다. 따라서 파라메트릭 서치로 문제를 풀 때 True or False 인지를 판별하는 함수의 시간복잡도를 고려하여 풀어야한다.
def promising(stones,mid,k):
cnt = 0
for s in stones:
if s >= mid: cnt = 0
else: cnt += 1
if cnt == k:
return False
return True
def solution(stones,k):
left, right = 1,sum(stones)
result = 0
while left <= right:
mid = (left + right) // 2
if promising(stones[:],mid,k):
left = mid + 1
result = mid
else:
right = mid - 1
return result