f8b21af4be
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.1 KiB
6.1 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-binary-search | Binary Search | 10_Wiki/Topics | verified | self |
|
none | A | 0.97 | applied |
|
2026-05-10 | pending |
|
Binary Search
📌 한 줄 통찰
"매 절반씩 의 탐색". 매 sorted array 의 매 O(log N). 매 100만 = 매 20 step. 매 algorithm 의 elegance 의 가장. 매 git bisect / parametric search / boundary find 의 same 원리.
📖 핵심
매 algorithm
- 매 mid = (lo + hi) / 2.
- 매 target == mid → return.
- 매 target < mid → hi = mid - 1.
- 매 target > mid → lo = mid + 1.
- 매 lo > hi → not found.
매 complexity
- Time: O(log N). 매 100만 = 20 comparison.
- Space: O(1) iterative / O(log N) recursive.
- Precondition: 매 sorted (or monotonic predicate).
매 variant
Lower bound (first ≥ target)
- 매 첫 매 element ≥ target.
Upper bound (first > target)
- 매 첫 매 element > target.
Range [first, last]
- 매 lower / upper 의 결합.
Bisection on continuous
- 매 root finding (math).
- 매 epsilon-based termination.
Parametric search
- 매 monotonic predicate 의 boundary.
- 매 "최대 X 의 Y 의 OK" 의 search.
Galloping (exponential + binary)
- 매 unbounded 의 매 growing range 의 binary.
매 trap
- Overflow:
(lo + hi) / 2의 int overflow →lo + (hi - lo) / 2. - Off-by-one: lo / hi / mid 의 boundary.
- Infinite loop: 매 mid 의 적절한 update.
- Sorted assumption: 매 unsorted 의 fail.
- Float precision: 매 epsilon 의 fix.
매 응용
bisectmodule (Python).std::lower_bound(C++).- DB index (B-tree): 매 internal node search.
git bisect: 매 commit 의 first bad.- Parametric (LeetCode): "min capacity for delivery in D days".
- Hyperparameter tune: 매 LR sweep.
- Quantile estimate: 매 streaming.
매 modern variant
- Branchless binary search: 매 conditional move.
- Eytzinger layout: 매 cache-friendly.
- Interpolation search: 매 uniform 의 O(log log N).
- Fractional cascading: 매 multi-list.
💻 패턴
Classic (iterative)
def binary_search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = lo + (hi - lo) // 2
if arr[mid] == target: return mid
if arr[mid] < target: lo = mid + 1
else: hi = mid - 1
return -1
Lower bound (first ≥)
def lower_bound(arr, target):
lo, hi = 0, len(arr)
while lo < hi:
mid = lo + (hi - lo) // 2
if arr[mid] < target: lo = mid + 1
else: hi = mid
return lo # 매 insertion point
Python bisect
import bisect
arr = [1, 3, 5, 7, 9]
bisect.bisect_left(arr, 5) # 2
bisect.bisect_right(arr, 5) # 3
bisect.insort(arr, 6) # 매 maintain sorted
Parametric search ("min eat speed")
def min_eating_speed(piles, h):
def can_eat(k):
return sum((p + k - 1) // k for p in piles) <= h
lo, hi = 1, max(piles)
while lo < hi:
mid = lo + (hi - lo) // 2
if can_eat(mid): hi = mid
else: lo = mid + 1
return lo
→ 매 monotonic predicate 의 boundary.
Bisection on float (root)
def find_root(f, lo, hi, eps=1e-9):
while hi - lo > eps:
mid = (lo + hi) / 2
if f(mid) * f(lo) < 0: hi = mid
else: lo = mid
return (lo + hi) / 2
# sqrt(2) 의 root of x² - 2 = 0
result = find_root(lambda x: x*x - 2, 0, 2)
# 1.414213562373...
git bisect (CLI)
git bisect start
git bisect bad HEAD
git bisect good v1.0
# 매 매 step 의 매 commit 의 test
git bisect good # or 'bad'
# 매 log N step → 매 first bad commit
git bisect reset
→ 매 1000 commit 의 매 10 step 의 culprit 의 find.
Galloping (exponential + binary)
def galloping_search(arr, target):
if arr[0] == target: return 0
bound = 1
while bound < len(arr) and arr[bound] < target:
bound *= 2
lo = bound // 2
hi = min(bound, len(arr) - 1)
return binary_search_range(arr, target, lo, hi)
→ 매 unbounded / online stream 의 OK.
Eytzinger layout (cache-friendly)
def eytzinger_search(arr, target):
"""매 BFS layout — 매 cache miss 매 minimize."""
n = len(arr)
k = 1
while k <= n:
if arr[k-1] < target: k = 2*k + 1
elif arr[k-1] > target: k = 2*k
else: return k - 1
return -1
🤔 결정 기준
| 상황 | 사용 |
|---|---|
| Sorted array search | binary search |
| Sorted insert | bisect.insort |
| Predicate boundary | parametric search |
| Float root | bisection method |
| Commit debugging | git bisect |
| Streaming quantile | binary search + treap |
| Cache-critical | Eytzinger layout |
기본값: Python bisect / C++ lower_bound 사용. 매 직접 구현 X.
🔗 Graph
- 부모: Search
- 변형: Lower-Bound · Upper-Bound
- 응용: Git-Bisect · B-Tree · Sorting
🤖 LLM 활용
언제: 매 sorted data search. 매 monotonic boundary. 매 root finding. 매 commit debugging. 언제 X: 매 unsorted (sort 의 cost X). 매 small N (linear OK). 매 non-monotonic.
❌ 안티패턴
(lo + hi) / 2overflow: 매 large array 의 fail.- Sorted assumption 위반: 매 wrong result.
while lo < hivs<=의 confusion: 매 off-by-one.- Float epsilon 무시: 매 무한 loop.
- Library 무시 + 직접 구현: 매 bug.
- Linear search 의 substitute (small N): 매 over-engineering.
🧪 검증 / 중복
- Verified (CLRS, Knuth TAOCP, classic).
- 신뢰도 A.
- Related: Sorting · Divide-and-Conquer · Git-Bisect · B-Tree.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — variant + parametric + 매 git bisect + 매 Eytzinger + code |