İçeriğe atla
ΣDSA Patterns
Menü
Dil

Kalıp #04

İkili Arama

Temel

Sıralı veya monoton arama uzayını yarıya bölerek cevabı sabitle.

Ne zaman kullanılır

Arama uzayı sıralı, döndürülmüş-sıralı veya monoton bir \"feasible(mid)\" predikatı. Yalnızca \"dizide hedef bul\" değil.

Tanıma ipuçları

  • Sıralı dizi (veya kısmen sıralı)
  • İlk/son/ekleme pozisyonu bul
  • Döndürülmüş sıralı dizi
  • Bitonik özellikte tepe bulma

Yaygın tuzaklar

  • Sonsuz döngü: exclusive sınırla lo < hi veya dikkatli lo + 1 < hi
  • Mid taşması: lo + ((hi - lo) >> 1) tercih et
  • Lower-bound ile tam eşleşmeyi karıştırmak

90 saniyelik tanıma egzersizi

Hangisi en iyi uyuyor?

  • Sıralı dizi (veya kısmen sıralı)
  • İlk/son/ekleme pozisyonu bul
  • Döndürülmüş sıralı dizi

Interactive

Zihinsel model

Değişmezin tam adım adım anlatımı. Duraklat, noktalara tıkla veya ← → kullan. Her adımı kendi cümlelerinle anlatmayı hedefle.

Adım 1 / 8
-1
lo
0
3
5
mid
9
12

a[mid] = 5

Half-open search space [lo, hi). Target = 9.

Nasıl düşünülür

Cevabı içermesi gereken aralığı koru. Ortayı sına; monoton teste göre yarısını at. Lower-bound formunu tercih et: lo = 0, hi = n (exclusive), lo == hi olana kadar daralt.

Şablon kontrol listesi

  1. Arama uzayı nedir? (indeks, değer, cevap aralığı)
  2. feasible(mid) ne demek?
  3. İlk true mu son true mu istiyorsun?
  4. Boş dizi ve tek eleman kenar durumlarını ele al.

Karmaşıklık temeli

O(log n) zaman, yinelemeli formda O(1) alan.

Şablon

TypeScript, Python ve C#’te aynı iskelet. Değişmezi uyarla; yapıyı koru.

İkili Arama · Şablon
/** Binary search template: lower-bound, then exact match. */
export function binarySearch(nums: number[], target: number): number {
  let lo = 0, hi = nums.length;
  while (lo < hi) {
    const mid = lo + ((hi - lo) >> 1);
    if (nums[mid]! < target) lo = mid + 1;
    else hi = mid;
  }
  return lo < nums.length && nums[lo] === target ? lo : -1;
}
/** Binary search template: lower-bound, then exact match. */
export function binarySearch(nums: number[], target: number): number {
  let lo = 0, hi = nums.length;
  while (lo < hi) {
    const mid = lo + ((hi - lo) >> 1);
    if (nums[mid]! < target) lo = mid + 1;
    else hi = mid;
  }
  return lo < nums.length && nums[lo] === target ? lo : -1;
}