Kalıp #03
Hızlı ve Yavaş İşaretçi
TemelBağlı listelerde döngü, orta düğüm ve sabit işaretçi aralığı.
Ne zaman kullanılır
Bağlı listelerde (veya döngüsel dizilerde) orta, döngü veya k düğümlük boşluk gerektiğinde; uzunluğu önceden bilmeden.
Tanıma ipuçları
- Bağlı liste döngü tespiti
- Listenin ortasını bul
- Sondan n. düğümü sil (n boşluk)
- Palindrom bağlı liste (orta bul, yarısını ters çevir)
Yaygın tuzaklar
- fast.next.next öncesi fast.next null kontrolü
- "Sondan n." için boşluğu konumlandırırken off-by-one
- İlk düğümü silerken head yeniden bağlamayı unutmak
90 saniyelik tanıma egzersizi
Hangisi en iyi uyuyor?
- Bağlı liste döngü tespiti
- Listenin ortasını bul
- Sondan n. düğümü sil (n boşluk)
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
2
3
4
5
Slow steps +1, fast steps +2. No need to know the list length.
Nasıl düşünülür
İki işaretçi farklı hızlarda (veya sabit ofsetle) ilerler. Hızlı bitince yavaş faydalı bir konumdadır (orta, reset sonrası döngü girişi vb.). Liste uzunluğunu önceden bilmeye gerek yok.
Klasik sonuçlar
- Döngü: buluşurlarsa döngü vardır (Floyd).
- Orta: hızlı sona varınca yavaş ortadadır.
- Sondan n.: hızlıyı n ilerlet, sonra ikisini hızlı bitene kadar yürüt.
Karmaşıklık temeli
O(n) zaman, O(1) ekstra alan, listeyi saklamaya tercih etmenin ana nedeni.
Şablon
TypeScript, Python ve C#’te aynı iskelet. Değişmezi uyarla; yapıyı koru.
Hızlı ve Yavaş İşaretçi · Şablon
/** Fast/slow template: detect cycle (Floyd). */
export class ListNode {
val: number;
next: ListNode | null;
constructor(val = 0, next: ListNode | null = null) {
this.val = val; this.next = next;
}
}
export function hasCycle(head: ListNode | null): boolean {
let slow = head, fast = head;
while (fast?.next) {
slow = slow!.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
}
/** Fast/slow template: detect cycle (Floyd). */
export class ListNode {
val: number;
next: ListNode | null;
constructor(val = 0, next: ListNode | null = null) {
this.val = val; this.next = next;
}
}
export function hasCycle(head: ListNode | null): boolean {
let slow = head, fast = head;
while (fast?.next) {
slow = slow!.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
}
#DurumProblemTürZorlukBitti
- 1#19 Remove Nth Node From End of ListRehbermedium
- 2#141 Linked List CycleRehbereasy
- 3#142 Linked List Cycle IIRehbermedium
- 4#160 Intersection of Two Linked ListsRehbereasy
- 5#234 Palindrome Linked ListRehbereasy
- 6#876 Middle of the Linked ListRehbereasy