본문 바로가기
Python Algorithm

이분 탐색의 원리 + 백준 1920 수 찾기

by woo0doo 2022. 12. 21.

이분 탐색의 이분은 '둘로 나눈다'는 뜻이다. 탐색할 자료를 둘로 나누어 찾는 값이 있을 법한 곳만 탐색하기 때문에

자료를 하나하나 찾아야 하는 순차 탐색보다 원하는 자료를 훨씬 빨리 찾을 수 있다.

 

 

600page 책을 펼치는 과정으로 예시를 들면

 

1. 책 510쪽을 펴야한다고 가정.

2. 책의 중간쯤 펼쳐 300쪽이 나옴

3. 찾고자 하는 510은 300쪽보다 뒤에 있음. 따라서 300쪽 앞인 1~300쪽은 더 이상 찾을 필요가 없다.

4. 301~600 사이에 중간쯤을 또 펼쳐 450p가 나옴. 510은 더 뒤에 있음. 301~450 배제.

5. 이 과정을 반복하며 원하는 510쪽이 나오면 탐색을 멈춘다.

 

이렇게 하게되면 이분 탐색의 계산 복잡도는 O(logn)으로, 순차 탐색의 계산 복잡도인 O(n)보다 훨씬 효율적이게 된다.

 

이를 코드로 하면

 

import sys
num = int(input())
#모든 책 페이지가 리스트 형태로 주어진다고 가정
bookNum = list(map(int,sys.stdin.readline().split()))
#이분 탐색은 리스트가 정렬되어 있어야함.
# 1,7,3,4 이런식으로 되어있으면 이분탐색은 이루어질 수 없다
bookNum.sort()

start=0
end = len(bookNum)-1
result=1  # 시도한 횟수
while start<=end:
    mid=(start + end) // 2
    if num == bookNum[mid]:
        print(result)
        break
    elif num > bookNum[mid]:
        start = mid + 1
        result+=1
    else:
        end = mid - 1
        result+=1

이런 식으로 코드가 짜여지게 된다.

이를 활용해 백준의 1920번을 풀 수 있게 된다.

import sys
n=int(input())
num1=list(map(int,sys.stdin.readline().split()))
n2=int(input())
num2=list(map(int,sys.stdin.readline().split()))

num1.sort()

for i in num2:
    start=0
    end=len(num1)-1
    while start <= end:
        mid = (start+end) // 2
        if i == num1[mid]:
            print(1)
            break
        elif i > num1[mid]:
            start = mid+1
        else:
            end=mid-1
    else:
        print(0)

이런 식으로 이분탐색을 해서 정답을 맞았는데....

N = int(input())
A = set(input().split())
M = int(input())
num = input().split()

for i in num:
    if i in A:
        print("1")
    else :
        print("0")

다른사람의 것을 보니 안해도 됐었다는 것은 비밀.......