bisect 라이브러리는 파이썬에서 이진탐색을 쉽게 구현하게 해 주는 라이브러리입니다.
알고리즘 시험에서 탐색 문제를 해결하기위해 이분탐색을 사용하는 경우가 많은데,
이분 탐색을 직접 구현하지 않고 라이브러리 만으로 수행할 수 있습니다.
bisect 라이브러리
✔️ bisect_left( x, i ) : 정렬된 배열 x에서 정렬 순서를 유지한 상태로 값 i를 삽입할 가장 왼쪽 인덱스 반환
✔️ bisect_right( x, i ) : 정렬된 배열 x에서 정렬 순서를 유지한 상태로 값 i를 삽입할 가장 오른쪽 인덱스 반환
예제 1
x = [1, 2, 3, 3, 3, 4, 5, 6]인 정렬된 배열이 있습니다.
이때 배열 x에 정렬된 상태 그대로 3이라는 숫자를 삽입하는 문제를 생각해 보겠습니다.
이분 탐색 ( bisect 사용 X )
nums = [1,2,3,3,3,4,5,6]
n = 3
l = 0
r = len(nums)-1
result = 0
while l <= r:
mid = (l+r) // 2
if nums[mid] >= n:
result = mid
r = mid - 1
else:
l = mid + 1
print(result)
## 결과값 : 2
일반적인 이분탐색을 이용하면 left 값과 right 값을 각각 시작 인덱스, 마지막 인덱스로 설정하여 mid 값을 변경하는 방식으로 구현할 수 있습니다. 이분탐색을 이용하면 O(logN)의 비용으로 탐색을 완료할 수 있습니다.
그럼 bisect library를 쓰면 얼마나 간단히 구할 수 있는지 보겠습니다.
bisect 사용 이분 탐색
from bisect import bisect_left, bisect_right
nums = [1,2,3,3,3,4,5,6]
n = 3
print(bisect_left(nums, n)) ## 결과 : 2
print(bisect_right(nums, n)) ## 결과 : 5
위 코드를 보면 bisect_left 함수는 3이 들어갈 수 있는 가장 왼쪽 인덱스를 반환합니다. 반면 bisect_right 함수는 3이 들어갈 수 있는 가장 오른쪽 인덱스를 반환합니다.
예제 2
이번에는 정렬된 배열에서 특정 범위에 속하는 원소의 개수를 구하는 문제를 살펴보겠습니다.
배열 x = [ 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 10 ] 이 있을 때 3 이상 7 이하의 값을 가지는 원소의 개수를 찾겠습니다.
from bisect import bisect_left, bisect_right
x = [1,2,3,3,3,4,5,6,7,7,7,8,9,10]
r_i = bisect_right(x, 7)
l_i = bisect_left(x, 3)
print(r_i - l_i) ## 결과 : 9
3 이상의 수를 찾기 위해 bisect_left 함수를 이용해 3이 들어갈 수 있는 가장 왼쪽 인덱스를 반환합니다.
7 이하의 수를 찾기 위해 bisect_right 함수를 이용해 7이 들어갈 수 있는 가장 오른쪽 인덱스를 반환합니다.
두 인덱스를 빼주면 3과 7 범위에 속하는 원소의 개수인 9가 반환됩니다.
'개발공부 > Python알고리즘' 카테고리의 다른 글
[Python] SQRT Decomposition(제곱근 분할법) 설명 및 구현 (백준14438, 2042) (1) | 2023.09.26 |
---|---|
[Python] 바이너리 인덱스 트리(BIT, 펜윅 트리) 구현 (1) | 2023.06.04 |
[Python] Segment Tree(세그먼트 트리) 설명 및 구현(백준 2042번) (1) | 2023.06.04 |
[Python]dictionary를 이용한 알고리즘 시간 단축(feat. hashtable) (0) | 2023.02.04 |
[Python] Flask vs FastAPI vs gRPC 비교와 예제 (0) | 2023.01.29 |
댓글