반응형
snowman95
코딩수련장
snowman95
전체 방문자
오늘
어제
  • 분류 전체보기 (229)
    • 앱테크 (3)
    • 옵시디언 (5)
    • 드라마, 영화 (1)
    • 개발자 이야기 (23)
    • 프로젝트 (10)
      • 프로젝트 방법론 (7)
      • 프로젝트 기록 (2)
      • Github (1)
    • 개발 지식 (0)
      • 디자인 패턴 (0)
    • 프론트엔드 개발 (5)
      • 테크트리 (2)
      • React.js (19)
      • ReactNative (2)
      • Next.js (6)
      • GraphQL (6)
      • 패키지 매니저 (2)
      • 라이브러리 (3)
      • 상태관리 라이브러리 (4)
      • Web 지식 (3)
      • HTML CSS (26)
      • Javascript (16)
      • 도구 (Tool) (3)
      • 성능 최적화 (1)
      • 디자인시스템 (0)
    • Python (53)
      • 모음집 (1)
      • 문법 (12)
      • 라이브러리 (15)
      • 알고리즘 (10)
      • 백준 문제풀이 (9)
      • 코딩테스트 (2)
      • 도구 (Tool) (3)
    • C++ (20)
      • 알고리즘 (6)
      • 삼성SW기출 (6)
      • 삼성 A형 (6)
    • 데이터사이언스 (1)
    • 인프라 (9)
      • 하드웨어 지식 (4)
      • Ansible (2)
      • Database (2)
      • 쉘스크립트 (1)
    • 주식 (0)
    • 취업 준비 (4)
      • 취업 이야기 (0)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 기계식키보드 #nuphy
  • 삼성SW역량테스트
  • GraphQL
  • 전공 요약 #네트워크
  • nextjs
  • 면접
  • 오블완
  • C++
  • 백준
  • Next.js #graphql #tailwind.css
  • 티스토리챌린지
  • 삼성SDS
  • 전공 요약 #데이터베이스
  • 알고리즘
  • 전공 요약 #운영체제
  • A형
  • 언어
  • 공간복잡도
  • 나의 해방일지
  • 전공요약

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
snowman95

코딩수련장

파이썬(python) 라이브러리 - bisect (이진탐색, 바이너리 서치, Binary Search)
Python/라이브러리

파이썬(python) 라이브러리 - bisect (이진탐색, 바이너리 서치, Binary Search)

2021. 4. 21. 15:58
728x90
반응형

이진탐색 (바이너리 서치, Binary Search)


정렬된 리스트에서 탐색 범위를 절반씩 좁혀나가며 빠르게 탐색하는 방법 

 

특징

탐색 범위가 매우 크게 주어짐 O(n) 인 선형탐색으로는 시간초과 나는 경우 사용가능

정렬된 리스트에서 특정 값을 매우 빠르게 찾고 싶을때 사용 

시간 복잡도 O(log N)

 

구현

1. bisect 라이브러리 사용

bisect.bisect_left(정렬된 리스트, target)

정렬된 리스트에서 target을 insert할때의 위치

 

bisect.bisect_right(정렬된 리스트, target)

정렬된 리스트에서 target을 insert할때의 위치+1

※ bisect.bisect는 bisect.bisect_right와 동일함

 

bisect.insert() 함수는 bisect함수와 동일하게 작동하고 해당 인덱스에 값을 삽입을 해준다.

(이 함수들은 c++의 upper_bound, lower_bound와 동일 → 대신 )

import bisect
a = [1,2,3,4,5]
x = 3
b = bisect.bisect_left(a,x)
2와 3 사이 인덱스인 2반환

c = bisect.bisect_right(a,x)
3과 4 사이 인덱스인 3반환

정렬된 리스트에서 특정 값이 몇번 등장하는지 확인
bisect.bisect_right(a, right) - bisect.bisect_left(a, left)

 

2. 직접 구현

def binary_serach(arr, target, start, end):
    while start <= end:
        mid = (start+end)//2
        if arr[mid] == target:
            return mid
        elif arr[mid] > target:
            end = mid-1
        else:
            start = mid + 1
    return None
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
(start ,mid, end)
(0, 5, 10)

if mid > target: 
(start ,mid, end)
(0, 2, 4)

elif mid > target:
(start ,mid, end)
(6, 8, 10)

 

 

예시

백준 12015 : 가장 긴 증가하는 부분 수열 2

 

12015번: 가장 긴 증가하는 부분 수열 2

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

www.acmicpc.net

import sys, bisect
n = int(sys.stdin.readline())
arr = list(map(int, sys.stdin.readline().split()))
inc_arr = [int(1e9)]*n

for i in range(0,n):
    idx = bisect.bisect_left(inc_arr, arr[i])
    if idx < n:
        inc_arr[idx] = arr[i]
        print(idx, arr[i],inc_arr)

print(inc_arr)
8
10 20 30 5 10 20 30 40

(idx, arr[i], inc_arr)
0 10 [10, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000]
1 20 [10, 20, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000]
2 30 [10, 20, 30, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000]
0 5 [5, 20, 30, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000]
1 10 [5, 10, 30, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000]
2 20 [5, 10, 20, 1000000000, 1000000000, 1000000000, 1000000000, 1000000000]
3 30 [5, 10, 20, 30, 1000000000, 1000000000, 1000000000, 1000000000]
4 40 [5, 10, 20, 30, 40, 1000000000, 1000000000, 1000000000]

정답
5

파라메트릭 서치 (Parametric Serch)


최적화 문제를 결정 문제(Yes or No)로 바꾸어 해결하는 기법

특정 조건 만족하는 가장 알맞은 값을 빠르게 찾는 최적화 문제에 사용됨

 

특징

탐색 범위가 매우 크게 주어짐 O(n) 인 선형탐색으로는 시간초과 나는 경우 사용가능

정렬된 리스트에서 범위를 중간값으로 잘랐을때 특정 조건을 만족하는지 확인할 때 사용됨

 

구현

바이너리 서치 함수 안에서 중간값으로 잘랐을때 어떤 조건을 만족하는지 확인

 

예시

백준 2805 : 나무 자르기

 

2805번: 나무 자르기

첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1 ≤ N ≤ 1,000,000, 1 ≤ M ≤ 2,000,000,000) 둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M보

www.acmicpc.net

import sys
n,m = map(int,sys.stdin.readline().split())
target = list(map(int,sys.stdin.readline().split()))
s = 0
e = 2**31-1
while s <= e:
    mid = (s+e)//2
    cnt = 0
    for t in target:
        if t > mid:
            cnt += t-mid
    if m <= cnt:
        s = mid+1
    else:
        e = mid-1
print(e)

 

반응형
저작자표시 동일조건

'Python > 라이브러리' 카테고리의 다른 글

파이썬(python) 라이브러리 - heapq  (0) 2021.05.07
파이썬(python) 라이브러리 - collections.deque  (0) 2021.04.22
파이썬(python) 라이브러리 - collections.Counter  (0) 2021.04.21
파이썬(python) 유용한 표준 라이브러리  (0) 2021.04.21
파이썬(python) 라이브러리 - itertools (순열, 조합, 누적합)  (0) 2021.04.21
    'Python/라이브러리' 카테고리의 다른 글
    • 파이썬(python) 라이브러리 - heapq
    • 파이썬(python) 라이브러리 - collections.deque
    • 파이썬(python) 라이브러리 - collections.Counter
    • 파이썬(python) 유용한 표준 라이브러리
    snowman95
    snowman95
    (17~19) Unity/Unreal Engine 게임 프로그래머 (20~21) System Administrator ___________ (22~) React 웹 프론트앤드 개발자 __________ 깃헙 : https://github.com/snowman95

    티스토리툴바