Kalıp #11
Kuyruk ve Deque
ÖnerilenFIFO işleme, kayar pencerede ekstremum ve son olay takibi.
Ne zaman kullanılır
İşleme sırası önemliyse (BFS benzeri) veya hareketli pencerede amortize O(1) min/maks lazımsa.
Tanıma ipuçları
- Kayar pencere maksimumu
- Hareketli ortalama / vuruş sayacı
- Dairesel kuyruk / son çağrılar tasarla
Yaygın tuzaklar
- Pencereden çıkan indeksleri çıkarmayı unutmak
- Python'da list pop(0) (O(n)) yerine deque kullanmamak
- Dahil pencere sınırlarında off-by-one
90 saniyelik tanıma egzersizi
Hangisi en iyi uyuyor?
- Kayar pencere maksimumu
- Hareketli ortalama / vuruş sayacı
- Dairesel kuyruk / son çağrılar tasarla
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.
front = current max index
Sliding window maximum with k = 3. Deque holds candidates decreasing.
Nasıl düşünülür
Kuyruk varış sırasını korur. Monoton deque pencere min/maks aday indekslerini tutar: ön her zaman cevap; arka ezilen değerleri atar. Kayar pencereyle her indeks bir girer bir çıkar.
Şablon şekilleri
| Şekil | Temel hamle | Notlar |
|---|---|---|
| FIFO kuyruk | Enqueue / dequeue | BFS, tampon |
| Monoton deque | Daha kötüyse arkadan pop | Pencere max/min |
| Zaman penceresi | Süresi dolanı önden at | Vuruş sayacı |
Karmaşıklık temeli
Pencere ekstremum için amortize O(n); basit kuyruk tasarımlarında işlem başına O(1).
Şablondan probleme
- İki uç gerekip gerekmediğine göre queue vs deque seç.
- Pencere max için deque’de azalan değerleri koru.
- Pencereden çıktıysa önü at; arkayı temizledikten sonra yeni indeksi push et.
- Pencere dolduktan sonra önü kaydet.
Şablon
TypeScript, Python ve C#’te aynı iskelet. Değişmezi uyarla; yapıyı koru.
/** Deque template: sliding window maximum. */
export function maxSlidingWindow(nums: number[], k: number): number[] {
const dq: number[] = [];
const res: number[] = [];
for (let i = 0; i < nums.length; i++) {
while (dq.length && dq[0]! <= i - k) dq.shift();
while (dq.length && nums[dq[dq.length - 1]!]! <= nums[i]!) dq.pop();
dq.push(i);
if (i >= k - 1) res.push(nums[dq[0]!]!);
}
return res;
}
/** Deque template: sliding window maximum. */
export function maxSlidingWindow(nums: number[], k: number): number[] {
const dq: number[] = [];
const res: number[] = [];
for (let i = 0; i < nums.length; i++) {
while (dq.length && dq[0]! <= i - k) dq.shift();
while (dq.length && nums[dq[dq.length - 1]!]! <= nums[i]!) dq.pop();
dq.push(i);
if (i >= k - 1) res.push(nums[dq[0]!]!);
}
return res;
}
- 1#239 Sliding Window MaximumRehberhard
- 2#346 Moving Average from Data StreamRehbereasy
- 3#362 Design Hit CounterRehbermedium
- 4#622 Design Circular QueueRehbermedium
- 5#641 Design Circular DequeRehbermedium
- 6#933 Number of Recent CallsRehbereasy