리스트 안에 있는 특정 데이터를 찾기 위해 앞에서부터 순회하며 데이터를 하나씩 확인하는 방법
정렬되어 있는 리스트에서 탐색 범위를 절반씩 좁혀가며 데이터를 탐색하는 방법
시작점, 끝점, 중간점을 이용하여 탐색 범위를 설정
정렬되어 있는 리스트에서만 사용 가능
시간 복잡도는 O(logN)
Tip
이진 탐색의 아이디어는 숫자 맞추기 게임의 승리 전략과 유사하다.
ex.) 상대가 1~10 사이의 숫자 중 하나를 정했을 때 그 숫자가 무엇인지 맞추는 게임을 할 때 가장 일반적인 전략은 범위의 중위값부터 범위를 반씩 좁혀나가면서 비교하는 것이다.
def binary_search(array, target, start, end):
if start > end:
return None
mid = (start + end) // 2
if array[mid] == target:
return mid
elif array[mid] > target:
return binary_search(array, target, start, mid-1)
else:
return binary_search(array, target, mid+1, end)
n, target = list(map(int, input().split()))
array = list(map(int, input().split()))
result = binary_search(array, target, 0, n-1)
if result == None:
print('원소가 존재하지 않습니다.')
else:
print(result + 1)
def binary_search(array, target, start, end):
while start <= end:
mid = (start + end) // 2
if array[mid] == target:
return mid
elif array[mid] > target:
end = mid-1
else:
start = mid+1
return None
n, target = list(map(int, input().split()))
array = list(map(int, input().split()))
result = binary_search(array, target, 0, n-1)
if result == None:
print('원소가 존재하지 않습니다.')
else:
print(result + 1)
정렬된 배열과 원소를 인자로 받아서 정렬된 배열 안에서 정렬을 유지하며 원소를 삽입할 수 있는 위치(인덱스) 반환(왼쪽부터 or 오른쪽부터)
from bisect import bisect_left, bisect_right
a = [1,2,4,4,8]
x = 4
print(bisect_left(a,x)) # 2
print(bisect_right(a,x)) # 4
def count_by_range(array, left_value, right_value):
right_index = bisect_right(array, right_value)
left_index = bisect_left(array, left_value)
return right_index - left_index
파라메트릭 서치(Parametric Search): 최적화 문제를 결정 문제('예' 혹은 '아니오')로 바꾸어 해결하는 기법
ex.) 특정한 조건을 만족하는 가장 알맞은 값을 빠르게 찾는 최적화 문제
일반적으로 코딩 테스트에서 파라메트릭 서치 문제는 이진 탐색을 이용하여 해결 가능