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

Kalıp #31

Linked List Manipulation

Temel

Ters çevirme, yerinde birleştirme, dummy head, splice, partisyon.

Ne zaman kullanılır

Bağlı listeyi yerinde yeniden yapılandırırken: ters çevirme, birleştirme, splice, partisyon, döndürme. Döngü/orta tespit eden fast-slow ile farklı.

Tanıma ipuçları

  • Bağlı listeyi ters çevirme / birleştirme / partisyon
  • Yerinde düğüm yeniden düzenleme (yeni liste yok)
  • Head kenar durumları için dummy head
  • Grup takası / döndürme / k-group

Yaygın tuzaklar

  • Yeniden atamadan önce next pointerı kaybetmek (çiz)
  • Head kenar durumları için dummy head unutmak
  • Son nexti null yapmayarak döngü oluşturmak

90 saniyelik tanıma egzersizi

Hangisi en iyi uyuyor?

  • Bağlı listeyi ters çevirme / birleştirme / partisyon
  • Yerinde düğüm yeniden düzenleme (yeni liste yok)
  • Head kenar durumları için dummy head

Etkileşimli

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

prev = null, cur = baş

1→2→3→4→5'i yerinde ters çevir. Altın kural: ezmeden önce next'i kaydet.

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

Bağlı liste manipülasyonu pointer yeniden bağlamadır. Yeni düğüm ayırmazsın; mevcut düğümleri yeniden sıralamak için next pointerlarını yeniden atarsın. Temel kural: next’i ezmeden önce eski değeri kaydet, yoksa listenin geri kalanını kaybedersin. Her adımı çiz, off-by-one burada sessiz bir bozulmadır, çökme değil.

Dummy head (sentinel) en yararlı alışkanlıktır. dummy.next’i gerçek head’e yönlendirerek “head’e ekle/sil” özel durumunu ortadan kaldırırsın: her işlem bir “önceki-düğüm” işlemine dönüşür ve yeni head her zaman dummy.next olur.

Şablon şekilleri

Şekil Temel hamle Örnek
Tam ters çevirme prev, cur, nxt üçlüsü LC 206
[a, b) aralığını ters çevir cur === b olana kadar ters çevir LC 92, LC 25 (k-group)
İki sıralıyı birleştir Dummy + head karşılaştır LC 21
Partisyon / gruplama İki dummy kuyruk (sol/sağ), sonunda bağla LC 328

Karmaşıklık temeli

O(n) zaman, O(1) ekstra alan (birkaç pointer). Temel nokta: listeyi kopyalamaktan kaçın. Yeni liste ayırırsan yavaş yolu yapıyorsun.

Şablondan probleme

  1. İşlemi tanımla: ters çevirme, birleştirme, splice, partisyon veya kombinasyonu.
  2. Yeni head nerede olacak, değişebiliyorsa dummy ile koru.
  3. Yeniden yazmadan önce next’i kaydet; döngüyü önlemek için son next’i null yap.
  4. dummy.next’i (veya yakalanan yeni head’i) döndür, eski head referansı asla.

Şablon

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

Linked List Manipulation · Şablon
/** Linked list manipulation template: reverse + merge with dummy head. */
export class ListNode {
  val: number;
  next: ListNode | null;
  constructor(val = 0, next: ListNode | null = null) {
    this.val = val; this.next = next;
  }
}

export function reverseList(head: ListNode | null): ListNode | null {
  let prev: ListNode | null = null;
  let cur = head;
  while (cur) {
    const nxt = cur.next;
    cur.next = prev;
    prev = cur;
    cur = nxt;
  }
  return prev;
}

export function mergeTwoLists(a: ListNode | null, b: ListNode | null): ListNode | null {
  const dummy = new ListNode();
  let tail = dummy;
  while (a && b) {
    if (a.val <= b.val) { tail.next = a; a = a.next; }
    else { tail.next = b; b = b.next; }
    tail = tail.next;
  }
  tail.next = a ?? b;
  return dummy.next;
}
/** Linked list manipulation template: reverse + merge with dummy head. */
export class ListNode {
  val: number;
  next: ListNode | null;
  constructor(val = 0, next: ListNode | null = null) {
    this.val = val; this.next = next;
  }
}

export function reverseList(head: ListNode | null): ListNode | null {
  let prev: ListNode | null = null;
  let cur = head;
  while (cur) {
    const nxt = cur.next;
    cur.next = prev;
    prev = cur;
    cur = nxt;
  }
  return prev;
}

export function mergeTwoLists(a: ListNode | null, b: ListNode | null): ListNode | null {
  const dummy = new ListNode();
  let tail = dummy;
  while (a && b) {
    if (a.val <= b.val) { tail.next = a; a = a.next; }
    else { tail.next = b; b = b.next; }
    tail = tail.next;
  }
  tail.next = a ?? b;
  return dummy.next;
}
#DurumProblemTürBitti
  1. 1#21 Merge Two Sorted ListsRehber
  2. 2#24 Swap Nodes in PairsRehber
  3. 3#25 Reverse Nodes in k-GroupRehber
  4. 4#92 Reverse Linked List IIRehber
  5. 5#206 Reverse Linked ListRehber
  6. 6#328 Odd Even Linked ListRehber