정렬된 배열에서 타겟을 찾는 검색 알고리즘
자료구조인 이진 탐색 트리와 알고리즘 그 자체이다.
탐색할 자룔르 둘로 나누어 해당 데이터가 있을 만한 곳을 탐색하는 방법
분할 정복 알고리즘을 이용함
➡️ 이진 탐색
def binary_search(left,right):
if left<= right:
mid = (left+right)//2
if nums[mid]<target:
return binary_search(mid+1,right)
elif nums[mid]>target:
return binary_search(left,mid-1)
else:
return mid
else:
return -1
def binary_search():
left,right=0,len(nums)-1
while left<=right:
mid=(left+right)//2
if nums[mid]<target:
left=mid+1
elif nums[mid]>target:
right=mid-1
else:
return mid
return -1
def binary_search():
index=bisect.bisect_left(nums,target)
if index<len(nums) and nums[index]==target:
return index
else:
return -1
➡️ bisect라이브러리(모듈)은 '정렬된 리스트'에서 '값이 특정 범위에 속하는 원소의 개수'를 구할 때 사용하면 효율적이다.
# 효율적 예시
from bisect import bisect_left, bisect_right
# '정렬된 리스트'에서 `값이 특정 범위에 속하는 원소의 개수`를 구할 때 좋다.
def count_by_range(b, left_value, right_value):
right_index = bisect_right(b, right_value)
left_index = bisect_left(b, left_value)
print('right : ', right_index, 'left :', left_index)
return right_index - left_index
a = [1, 2, 3, 3, 3, 3, 4, 4, 8, 9]
print(count_by_range(a, 4, 4))
>>> right : 8 left : 6
>>> 2
# 리스트 a에 4는 총 2개 존재한다.
print(count_by_range(a, -1, 3))
>>> right : 6 left : 0
>>> 6
# 리스트 a에 -1~3사이의 값은 총 6개 존재한다.
n개의 리스트를 매번 2로 나누어 1이 될 때까지 비교연산을 k회 진행
n = 2^k = log2n = log22^k
log2n = k
k+1이 최종 시간 복잡도 (1일때도 비교연산 수행)
O(logn)
[참고]