Open seungriyou opened 3 months ago
μ΄λ ν groupμμ targetμ μ°ΎμΌλ €λ©΄, μ΅μ μ κ²½μ°μλ λͺ¨λ μμλ₯Ό λ€ νμΈν¨μΌλ‘μ¨ O(n)μ μμ μ μννκ² λλ€.
O(n)
νμ§λ§ μμλ€μ΄ μ λ ¬λμ΄ μλ€λ©΄, search timeμ O(logn)μΌλ‘ μ€μΌ μ μλ€.
O(logn)
lo
hi
lo & hiλ₯Ό μ΄κΈ°νν λλ κ°λ₯ν λͺ¨λ μ λ΅ λ²μλ₯Ό ν¬ν¨νλλ‘ νλ€.
μΌλ°μ μΌλ‘ λ°°μ΄μ μμμμ targetμ μ°Ύλ κ²½μ°, loμ hiλ λ°°μ΄μ μΈλ±μ€μ λ²μμ κ°λ€.
lo = 0 hi = len(nums) - 1
νμ§λ§ λ°°μ΄μ target μμλ₯Ό λΌμλ£λ λ± νΉμν κ²½μ°μλ λ€μκ³Ό κ°μ΄ hiλ₯Ό νλ λ κ³ λ €ν΄μΌ νλ€.
ex. 69. Sqrt(x) / 35. Search Insert Position
lo = 0 hi = len(nums)
mid κ³μ° μ μ€λ²νλ‘μ°μ lower/upper mid μ μ£Όμνλ€.
mid
μ€λ²νλ‘μ°κ° μΌμ΄λμ§ μλλ‘ νλ€.
int overflowκ° μλ Pythonμ μκ΄ μλ€κ³ μκ³ μμΌλ, lower/upper midλ₯Ό μ΄μ©νλ €λ©΄ λ λ²μ§Έ λ°©λ²μ΄ μ¬μ보μΈλ€.
# worst mid = (lo + hi) // 2 # much better, but still possible mid = lo + (hi - lo) // 2 # best mid = (lo + hi) >> 1
lower/upper mid μ€ μ μ ν κ²μ μ ννλ€. μλͺ» μ ννλ©΄ 무ν 루νμ λΉ μ§ μ μλ€.
β 5λ²μμ μμΈν λ€λ£¬λ€.
# lower(left) mid mid = lo + (hi - lo) // 2 # upper(right) mid mid = lo + (hi - lo + 1) // 2
κ²½κ³λ₯Ό μΆμν΄λκ° λ, midλ₯Ό μ μΈνλ λ‘μ§μ μ¬μ©νλ€.
λ¨μν λ Όλ¦¬λ₯Ό μν΄ λ¨μΌ μμ if ... elseλ₯Ό μ¬μ©νλ©°, νμ midλ₯Ό μ μΈνλ λ‘μ§μ μ¬μ©νλ€.
if ... else
κ°μΈμ μΈ κ²¬ν΄λ‘λ, midλ₯Ό μ μΈνλ λ‘μ§κ³Ό ν¬ν¨νλ λ‘μ§ μ€ λ μ§κ΄μ μΈ λ‘μ§μ μ¬μ©νλ νΈμ΄ μ’μ κ² κ°λ€.
if target < nums[mid]: hi = mid - 1 # mid is excluded else: lo = mid # mid is included
if target > nums[mid]: lo = mid + 1 # mid is excluded else: hi = mid # mid is included
while λ¬Έμ 쑰건μ νμ lo < hi λ‘ νλ κ²μ΄ κ°λ¨νλ€.
lo < hi
while lo < hi: 루νκ° μ’ λ£λλ μ μΌν 쑰건μ lo == hiμ΄λ©°, loμ hiκ° κ°μ μμλ₯Ό κ°λ¦¬ν¬ κ²μ΄λΌλ κ²μ μκ³ μμΌλ―λ‘ lo < hiλ₯Ό μ±ννλ€.
while lo < hi:
lo == hi
νμ§λ§ lo <= hiκ° λ μ§κ΄μ μΈ κ²½μ°κ° μμΌλ―λ‘, λμ λ°λΌ μ μ νκ² μ μ©νμ.
lo <= hi
ex. 162. Find Peak Element, 1901. Find a Peak Element II
무ν 루νλ₯Ό νΌνκΈ° μν΄μλ 2κ°μ μμκ° λ¨μμ λλ₯Ό κ³ λ €ν΄μΌ νλ€.
lower / upper midλ₯Ό μλͺ» μ ννλ©΄ 루νμμ μ무 μ λ°μ΄νΈλ μΌμ΄λμ§ μμ μ μκ³ (= μΆμκ° μΌμ΄λμ§ X), μ΄λ 곧 무ν 루νμ λΉ μ§κ² λλ€.
νλ‘κ·Έλ¨μ΄ 무ν 루νμ λΉ μ‘λ€λ©΄ loμ hiλ‘ μ€μ λ κ²½κ³ λ΄λΆμ λ κ°μ μμλ§ λ¨μμ λλ₯Ό μκ°ν΄μΌ νλ€.
lower midλ₯Ό μ¬μ©νλ λ€μμ μ½λλ λ κ°μ μμλ§ λ¨μμ λ μ무κ²λ νμ§ μμ(= μκΈ°μμ μΌλ‘ μΆμ) 무ν 루νμ λΉ μ§κ² λλ€. μ΄λ¬ν μ½λμμλ upper midλ₯Ό μ¬μ©ν΄μΌ νλ€.
mid = lo + (hi - lo) // 2 # lower mid if target < nums[mid]: hi = mid - 1 else: lo = mid
λ°λλ‘, upper midλ₯Ό μ¬μ©νλ λ€μμ μ½λλ λν 무ν 루νμ λΉ μ§κ² λλ€. μ΄λ¬ν μ½λμμλ lower midλ₯Ό μ¬μ©ν΄μΌ νλ€.
mid = lo + (hi - lo + 1) // 2 # upper mid if target > nums[mid]: lo = mid + 1 else: hi = mid
704. Binary Search λ¬Έμ λ₯Ό λ€μκ³Ό κ°μ΄ λ κ°μ§ midλ₯Ό λͺ¨λ μ¬μ©νμ¬ ν μ μλ€.
midλ₯Ό μ ννλ κ²κ³Ό κ²½κ³ μΆμ λ‘μ§μ νμ ν¨κ» μνλμ΄μΌ νλ©°, μ΄λλ§λ€ μ΅μ 1κ°μ μμκ° μ μΈλμ΄μΌ ν¨μ λͺ μ¬νλ€.
Minimize k, s.t. condition(k) is True
k
condition(k)
while loop λ΄μ if λ¬Έμμ λΉκ΅μ°μ°μλ₯Ό μ΄μ©ν΄μ νλ¨ν΄λ λμ§λ§, condition() ν¨μ μμμ boolean κ°μΌλ‘ νλ¨ν΄μ λ°ννλ©΄ λ κΉλνλ€!
while
if
condition()
λ¨, λ‘μ§μ μ€κ³νκΈ° μ΄λ €μΈ μ μμΌλ μ°μ if λ¬Έμμ λΉκ΅μ°μ°μλ₯Ό μ΄μ©νλ κ²λ μ’μ κ² κ°λ€.
def binary_search(array) -> int: def condition(value) -> bool: pass left, right = 0, len(array) while left < right: mid = left + (right - left) // 2 if condition(mid): right = mid else: left = mid + 1 return left
[!caution] condition ν¨μλ₯Ό μ΄λ»κ² μ€κ³ν΄μΌ νκ³ , μ΄λ₯Ό λ§μ‘±νλ κ° μ€ μ΄λ€ κ°μ μ°ΎμμΌ νλμ§λ₯Ό μ μκ°ν΄μΌ νλ€. (νΉν k-th μμλ₯Ό μ°Ύλ λ¬Έμ μ κ°μ΄ μ§κ΄μ μ΄μ§ μμ κ²½μ°...)
[!caution] condition ν¨μλ₯Ό μ΄λ»κ² μ€κ³ν΄μΌ νκ³ , μ΄λ₯Ό λ§μ‘±νλ κ° μ€ μ΄λ€ κ°μ μ°ΎμμΌ νλμ§λ₯Ό μ μκ°ν΄μΌ νλ€.
condition
(νΉν k-th μμλ₯Ό μ°Ύλ λ¬Έμ μ κ°μ΄ μ§κ΄μ μ΄μ§ μμ κ²½μ°...)
References
μ΄μ§ νμ(Binary Search)
μ΄λ ν groupμμ targetμ μ°ΎμΌλ €λ©΄, μ΅μ μ κ²½μ°μλ λͺ¨λ μμλ₯Ό λ€ νμΈν¨μΌλ‘μ¨
O(n)
μ μμ μ μννκ² λλ€.νμ§λ§ μμλ€μ΄ μ λ ¬λμ΄ μλ€λ©΄, search timeμ
O(logn)
μΌλ‘ μ€μΌ μ μλ€.μ΄μ§ νμ λ¬Έμ νμ΄ μ κ³ λ €ν΄μΌ νλ μΈ κ°μ§
lo
μhi
μ μ΄κΈ°κ°νμ΄ μμΉ
lo
&hi
λ₯Ό μ΄κΈ°νν λλ κ°λ₯ν λͺ¨λ μ λ΅ λ²μλ₯Ό ν¬ν¨νλλ‘ νλ€.μΌλ°μ μΌλ‘ λ°°μ΄μ μμμμ targetμ μ°Ύλ κ²½μ°,
lo
μhi
λ λ°°μ΄μ μΈλ±μ€μ λ²μμ κ°λ€.νμ§λ§ λ°°μ΄μ target μμλ₯Ό λΌμλ£λ λ± νΉμν κ²½μ°μλ λ€μκ³Ό κ°μ΄
hi
λ₯Ό νλ λ κ³ λ €ν΄μΌ νλ€.mid
κ³μ° μ μ€λ²νλ‘μ°μ lower/uppermid
μ μ£Όμνλ€.μ€λ²νλ‘μ°κ° μΌμ΄λμ§ μλλ‘ νλ€.
lower/upper
mid
μ€ μ μ ν κ²μ μ ννλ€. μλͺ» μ ννλ©΄ 무ν 루νμ λΉ μ§ μ μλ€.κ²½κ³λ₯Ό μΆμν΄λκ° λ,
mid
λ₯Ό μ μΈνλ λ‘μ§μ μ¬μ©νλ€.λ¨μν λ Όλ¦¬λ₯Ό μν΄ λ¨μΌ μμ
if ... else
λ₯Ό μ¬μ©νλ©°, νμmid
λ₯Ό μ μΈνλ λ‘μ§μ μ¬μ©νλ€.while λ¬Έμ 쑰건μ νμ
lo < hi
λ‘ νλ κ²μ΄ κ°λ¨νλ€.while lo < hi:
루νκ° μ’ λ£λλ μ μΌν 쑰건μlo == hi
μ΄λ©°,lo
μhi
κ° κ°μ μμλ₯Ό κ°λ¦¬ν¬ κ²μ΄λΌλ κ²μ μκ³ μμΌλ―λ‘lo < hi
λ₯Ό μ±ννλ€.νμ§λ§
lo <= hi
κ° λ μ§κ΄μ μΈ κ²½μ°κ° μμΌλ―λ‘, λμ λ°λΌ μ μ νκ² μ μ©νμ.무ν 루νλ₯Ό νΌνκΈ° μν΄μλ 2κ°μ μμκ° λ¨μμ λλ₯Ό κ³ λ €ν΄μΌ νλ€.
lower / upper
mid
λ₯Ό μλͺ» μ ννλ©΄ 루νμμ μ무 μ λ°μ΄νΈλ μΌμ΄λμ§ μμ μ μκ³ (= μΆμκ° μΌμ΄λμ§ X), μ΄λ 곧 무ν 루νμ λΉ μ§κ² λλ€.νλ‘κ·Έλ¨μ΄ 무ν 루νμ λΉ μ‘λ€λ©΄
lo
μhi
λ‘ μ€μ λ κ²½κ³ λ΄λΆμ λ κ°μ μμλ§ λ¨μμ λλ₯Ό μκ°ν΄μΌ νλ€.lower
mid
λ₯Ό μ¬μ©νλ λ€μμ μ½λλ λ κ°μ μμλ§ λ¨μμ λ μ무κ²λ νμ§ μμ(= μκΈ°μμ μΌλ‘ μΆμ) 무ν 루νμ λΉ μ§κ² λλ€. μ΄λ¬ν μ½λμμλ uppermid
λ₯Ό μ¬μ©ν΄μΌ νλ€.λ°λλ‘, upper
mid
λ₯Ό μ¬μ©νλ λ€μμ μ½λλ λν 무ν 루νμ λΉ μ§κ² λλ€. μ΄λ¬ν μ½λμμλ lowermid
λ₯Ό μ¬μ©ν΄μΌ νλ€.mid
λ₯Ό μ ννλ κ²κ³Ό κ²½κ³ μΆμ λ‘μ§μ νμ ν¨κ» μνλμ΄μΌ νλ©°, μ΄λλ§λ€ μ΅μ 1κ°μ μμκ° μ μΈλμ΄μΌ ν¨μ λͺ μ¬νλ€.κ°μ₯ μΌλ°μ μΈ ν νλ¦Ώ
while
loop λ΄μif
λ¬Έμμ λΉκ΅μ°μ°μλ₯Ό μ΄μ©ν΄μ νλ¨ν΄λ λμ§λ§,condition()
ν¨μ μμμ boolean κ°μΌλ‘ νλ¨ν΄μ λ°ννλ©΄ λ κΉλνλ€!λ¨, λ‘μ§μ μ€κ³νκΈ° μ΄λ €μΈ μ μμΌλ μ°μ
if
λ¬Έμμ λΉκ΅μ°μ°μλ₯Ό μ΄μ©νλ κ²λ μ’μ κ² κ°λ€.