Super Kawaii Cute Cat Kaoani
λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm/Python

[Python] 이진 탐색 μ•Œκ³ λ¦¬μ¦˜

728x90


πŸ’‘ 이진 탐색 μ•Œκ³ λ¦¬μ¦˜

순차 탐색 : μ•žμ—μ„œλΆ€ν„° ν•˜λ‚˜μ”© 확인.

이진 탐색 : μ •λ ¬λ˜μ–΄ μžˆλŠ” λ¦¬μŠ€νŠΈμ—μ„œ 탐색 λ²”μœ„ μ ˆλ°˜μ”© μ’ν˜€κ°€λ©΄μ„œ 탐색. μ‹œμž‘μ , 끝점, 쀑간점 이용.

 

βœ”οΈμ˜ˆμ‹œ [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]μ—μ„œ 4 μ°ΎκΈ°

 

1. μ‹œμž‘μ [0], 끝점[9], 쀑간점[4] (μ†Œμˆ˜μ  μ΄ν•˜ 제거)

0 2 4 6 8 10 12 14 16 18
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

쀑간점 κΈ°μ€€μœΌλ‘œ μ™Όμͺ½μ„ 탐색할지, 였λ₯Έμͺ½μ„ 탐색할지 κ³ λ₯΄κΈ° : μ°ΎλŠ” κ°’ 4κ°€ 8보닀 μž‘κΈ° λ•Œλ¬Έμ— μ™Όμͺ½μœΌλ‘œ

 

2. μ‹œμž‘μ [0], 끝점[3], 쀑간점[1]

0 2 4 6            
[0] [1] [2] [3]            

μ°ΎλŠ” κ°’ 4κ°€ 쀑간값 2보닀 크기 λ•Œλ¬Έμ— 였λ₯Έμͺ½μœΌλ‘œ

 

3. μ‹œμž‘μ [2], 끝점[3], 쀑간점[2]

    4 6            
    [2] [3]            

 

-> μ‹œκ°„λ³΅μž‘λ„ O(logN)

 

πŸ’‘ 파이썬 μ½”λ“œ : μž¬κ·€μ  κ΅¬ν˜„

쀑간값과 λΉ„κ΅ν•˜μ—¬ μ‹œμž‘ 인덱슀 λ˜λŠ” 끝 인덱슀λ₯Ό λ°”κΏ” μž¬κ·€μ μœΌλ‘œ κ΅¬ν˜„

 

βœ”οΈ μ½”λ“œ μ„€λͺ…

 

def 이진탐색 ν•¨μˆ˜ (λ°°μ—΄, μ°ΎλŠ” κ°’, μ‹œμž‘ 인덱슀, 끝 인덱슀):

    if μ‹œμž‘ 인덱슀 > 끝 인덱슀 : None

    쀑간 인덱슀 = ( μ‹œμž‘ + 끝 ) // 2

    if 쀑간 κ°’ == μ°ΎλŠ” κ°’ :  쀑간 인덱슀 λ°˜ν™˜

    elif μ°ΎλŠ” 값이 쀑간 값보닀 μž‘μœΌλ©΄ : μž¬κ·€(μ‹œμž‘ ~ 쀑간-1)

    else : μž¬κ·€(쀑간+1 ~ 끝)

 

μž…λ ₯λ°›κΈ° - μ›μ†Œ 개수(끝 인덱슀), 찾을 κ°’, 전체 μ›μ†Œ 리슀트

 

좜λ ₯κ°’ = 이진탐색 ν•¨μˆ˜(μž…λ ₯받은 κ°’)

print(λͺ‡λ²ˆμ§Έ μΈλ±μŠ€μΈμ§€)

 

βœ”οΈ μ½”λ“œ κ΅¬ν˜„

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 = map(int, input().split())
array = list(map(int, input().split()))

result = binary_search(array, target, 0, n-1)
if result == None: 
    print("μ°ΎλŠ” κ²°κ³Όκ°€ μ—†μŠ΅λ‹ˆλ‹€.")
else : 
    print("ν•΄λ‹Ή 값은 {}번째 μœ„μΉ˜μ— μžˆμŠ΅λ‹ˆλ‹€.".format(result+1))

 

μž…λ ₯ 좜λ ₯
10 7
1 3 5 7 9 11 13
ν•΄λ‹Ή 값은 {}번째 μœ„μΉ˜μ— μžˆμŠ΅λ‹ˆλ‹€.
10 7
1 3 5 6 9 11 13
μ°ΎλŠ” κ²°κ³Όκ°€ μ—†μŠ΅λ‹ˆλ‹€.

 

 

πŸ’‘ 파이썬 μ½”λ“œ : 반볡문 κ΅¬ν˜„

whileλ¬Έ μ‚¬μš©ν•˜μ—¬ μ‹œμž‘ μΈλ±μŠ€κ°€ 끝 μΈλ±μŠ€λ³΄λ‹€ μž‘μ€ κ²½μš°μ— 반볡 μ‹€ν–‰

 

βœ”οΈ μ½”λ“œ μ„€λͺ…

 

def 이진탐색 ν•¨μˆ˜ (λ°°μ—΄, μ°ΎλŠ” κ°’, μ‹œμž‘ 인덱슀, 끝 인덱슀):

    while μ‹œμž‘ 인덱슀 <= 끝 인덱슀:

        쀑간 인덱슀 = (μ‹œμž‘ 인덱슀 + 끝 인덱슀) // 2

        if 쀑간 κ°’ == μ°ΎλŠ” κ°’ : μ€‘κ°„ 인덱슀 λ°˜ν™˜

        elif 쀑간 κ°’ < μ°ΎλŠ” κ°’ : λ 인덱슀 = 쀑간 인덱슀 - 1

        else : μ‹œμž‘ 인덱슀 = 쀑간 인덱슀 + 1

    λͺ»μ°ΎμœΌλ©΄ None

 

μž…λ ₯λ°›κΈ° - μ›μ†Œ 개수(끝 인덱슀), 찾을 κ°’, 전체 μ›μ†Œ 리슀트

 

좜λ ₯κ°’ = 이진탐색 ν•¨μˆ˜(μž…λ ₯받은 κ°’)

print(λͺ‡λ²ˆμ§Έ μΈλ±μŠ€μΈμ§€)

 

βœ”οΈ μ½”λ“œ κ΅¬ν˜„

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 = map(int, input().split())
array = list(map(int, input().split()))

result = binary_search(array, target, 0, n-1)
if result == None: 
    print("μ°ΎλŠ” κ²°κ³Όκ°€ μ—†μŠ΅λ‹ˆλ‹€.")
else : 
    print("ν•΄λ‹Ή 값은 {}번째 μœ„μΉ˜μ— μžˆμŠ΅λ‹ˆλ‹€.".format(result+1))
μž…λ ₯ 좜λ ₯
10 7
1 3 5 7 9 11 13
ν•΄λ‹Ή 값은 {}번째 μœ„μΉ˜μ— μžˆμŠ΅λ‹ˆλ‹€.
10 7
1 3 5 6 9 11 13
μ°ΎλŠ” κ²°κ³Όκ°€ μ—†μŠ΅λ‹ˆλ‹€.

 

πŸ’‘ biscect 라이브러리

bisect_left(λ°°μ—΄, 숫자) : μ •λ ¬λœ μˆœμ„œ μœ μ§€ν•˜λ©΄μ„œ λ°°μ—΄ a에 xλ₯Ό 삽일할 κ°€μž₯ μ™Όμͺ½ 인덱슀

bisect_right(λ°°μ—΄, 숫자) : μ •λ ¬λœ μˆœμ„œ μœ μ§€ν•˜λ©΄μ„œ λ°°μ—΄ a에 xλ₯Ό 삽일할 κ°€μž₯ 였λ₯Έμͺ½ 인덱슀

1 2 4 4 8
[0] [1] [2] [3] [4]

μœ„μ˜ 리슀트의 ν˜•νƒœλ₯Ό λ°°μ—΄ a라고 ν•  λ•Œ, bisect_left(a, 4)λŠ” 2, bisect_right(a, 4)λŠ” 4

 

βœ”οΈ μ½”λ“œ κ΅¬ν˜„

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 개수 λ°˜ν™˜ ν•¨μˆ˜ (λ°°μ—΄, λ²”μœ„ 처음 수, λ²”μœ„ λ§ˆμ§€λ§‰ 수):

    였λ₯Έμͺ½ 인덱슀 = biscect_right(λ°°μ—΄, right_value)

    μ™Όμͺ½ 인덱슀 = biscect_left(λ°°μ—΄, right_left)

    return 였λ₯Έμͺ½ 인덱슀 - μ™Όμͺ½ 인덱슀

 

λ°°μ—΄ μ„ μ–Έ

print(개수 λ³€ν™˜ ν•¨μˆ˜(λ°°μ—΄, λ²”μœ„ 처음 수, λ²”μœ„ λ§ˆμ§€λ§‰ 수)

 

βœ”οΈ μ½”λ“œ κ΅¬ν˜„

from bisect import bisect_left, bisect_right

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

array = [1, 2, 3, 3, 3, 3, 4, 4, 8, 9]
print(count_by_range(array, 4, 4)) #2
print(count_by_range(array, -1, 3)) #6

 

728x90