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

Kalıp #08

Fark Dizisi

Önerilen

Aralık güncellemeleri O(1); diziyi önek geçişiyle yeniden kur.

Ne zaman kullanılır

Birçok güncelleme [L, R] aralığına değer ekliyor, sonra nihai dizi veya güncellemeler sonrası aralık sorguları gerekiyorsa.

Tanıma ipuçları

  • [L, R] her indeksine val ekle (çok kez)
  • Kurumsal uçuş rezervasyonları / aralık ekleme
  • Fark dizisi sonra önekle geri yükle

Yaygın tuzaklar

  • Aralık sonunu işaretlerken R+1 off-by-one
  • Değerleri okumadan önce son önek geçişini unutmak
  • Akış ortasında gerçek segment-tree karışık sorgular gerektiğinde bunu kullanmak

90 saniyelik tanıma egzersizi

Hangisi en iyi uyuyor?

  • [L, R] her indeksine val ekle (çok kez)
  • Kurumsal uçuş rezervasyonları / aralık ekleme
  • Fark dizisi sonra önekle geri yükle

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
0
0
0
0
0
0

diff starts at zeros

Range updates without touching every cell.

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

Aralıktaki her hücreyi güncellemek yerine diff dizisinde L’ye +v, R+1’e -v yaz. Tüm güncellemelerden sonra tek önek toplam değerleri yeniden kurar. Her güncelleme O(1); kurulum O(n).

Şablon şekilleri

Şekil Temel hamle Notlar
Aralık ekle diff[L]+=v; diff[R+1]-=v Sonra önek
Çoklu güncelleme Önce tüm aralık işlemlerini topla Tek kurulum
0-index vs 1-index Sınırlarda tutarlı ol R+1 = n olabilir

Karmaşıklık temeli

Aralık güncellemesi başına O(1), somutlaştırmak O(n). Diff için O(n) alan.

Şablondan probleme

  1. Uzunluk n (veya temiz R+1 için n+1) diff ayır.
  2. Her [L, R] += v: diff[L] += v; R+1 < n ise diff[R+1] -= v.
  3. Önek: i in 1..n-1: diff[i] += diff[i-1] (veya sonuca yaz).
  4. Cevapları yeniden kurulan diziden oku.

Şablon

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

Fark Dizisi · Şablon
/** Difference array template: range add then prefix rebuild. */
export function applyRangeUpdates(n: number, updates: number[][]): number[] {
  const diff = new Array(n + 1).fill(0);
  for (const [l, r, val] of updates) {
    diff[l!]! += val!;
    if (r! + 1 < diff.length) diff[r! + 1]! -= val!;
  }
  const out = new Array<number>(n);
  let run = 0;
  for (let i = 0; i < n; i++) {
    run += diff[i]!;
    out[i] = run;
  }
  return out;
}
/** Difference array template: range add then prefix rebuild. */
export function applyRangeUpdates(n: number, updates: number[][]): number[] {
  const diff = new Array(n + 1).fill(0);
  for (const [l, r, val] of updates) {
    diff[l!]! += val!;
    if (r! + 1 < diff.length) diff[r! + 1]! -= val!;
  }
  const out = new Array<number>(n);
  let run = 0;
  for (let i = 0; i < n; i++) {
    run += diff[i]!;
    out[i] = run;
  }
  return out;
}
#DurumProblemTürBitti
  1. 1#370 Range AdditionRehber
  2. 2#1094 Car PoolingRehber
  3. 3#1109 Corporate Flight BookingsRehber
  4. 4#1893 Check if All the Integers in a Range Are CoveredRehber
  5. 5#1943 Describe the PaintingRehber
  6. 6#2381 Shifting Letters IIRehber