Kalıp #01
Kayar Pencere
TemelDiziler ve stringlerde en uzun, en kısa veya geçerli bitişik aralıklar.
Ne zaman kullanılır
Problem en uzun, en kısa veya geçerli bitişik alt dizi/alt string istediğinde. Sıra serbestçe yeniden düzenlenebiliyorsa kullanma.
Tanıma ipuçları
- Bitişik alt dizi veya alt string
- En uzun / en kısa / en fazla K / tam K
- Sağı genişlet, değişmezi bozulunca solu daralt
Yaygın tuzaklar
- En iyi uzunluğu güncellerken off-by-one (right - left + 1)
- Daraltırken map/sayaç güncellemeyi unutmak
- İndekslerin bitişik olması gerekmediğinde kayar pencere kullanmak
90 saniyelik tanıma egzersizi
Hangisi en iyi uyuyor?
- Bitişik alt dizi veya alt string
- En uzun / en kısa / en fazla K / tam K
- Sağı genişlet, değişmezi bozulunca solu daralt
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.
best = 0
Start with an empty window. Invariant: all characters unique.
Nasıl düşünülür
Dizi üzerinde bir pencere [left, right] tut. right birer birer ilerlesin; pencere değişmezini bozunca left daralsın (çok fazla farklı karakter, toplam fazla, eksik zorunlu karakter…). Giderken en iyi geçerli pencereyi kaydet. Yukarıdaki animasyonun tamamı bu fikir: büyüt, düzelt, kaydet.
Şablon şekilleri
| Şekil | Ne zaman | Daraltma kuralı |
|---|---|---|
| Maks pencere | en uzun geçerli | geçersizken daralt |
| Min pencere | kısıtı kapsayan en kısa | geçerliyken daralt |
| Sabit boyut | boyut k |
her iki ucu kaydır |
Karmaşıklık temeli
Genelde O(n) zaman (her indeks en fazla bir girer/çıkar) ve frekans haritası için O(Σ) alan.
Şablondan probleme
- Değişmezi tanımla (pencereyi ne geçerli kılar?).
- Maks/min için genişletme/daraltma yönünü seç.
- Pencere durumunu belirle (sayım haritası, toplam, distinct küme…).
- Cevabı yalnızca değişmez sağlandığında güncelle.
Şablon
TypeScript, Python ve C#’te aynı iskelet. Değişmezi uyarla; yapıyı koru.
/**
* Sliding window (variable length), longest valid window.
* Expand `right`, shrink `left` while the invariant breaks, then record the answer.
*
* Minimum covering window: shrink while still valid, update `best` only when valid
* (often start with `best = Infinity`).
*/
function slidingWindow(s: string): number {
const freq = new Map<string, number>();
let left = 0;
let best = 0;
const windowOk = () => {
// Replace with the problem invariant (e.g. all unique, sum ≤ k).
return true;
};
for (let right = 0; right < s.length; right++) {
// 1) expand: add s[right] into window state
const add = s[right]!;
freq.set(add, (freq.get(add) ?? 0) + 1);
// 2) shrink while the invariant is broken
while (left <= right && !windowOk()) {
const rem = s[left]!;
const next = (freq.get(rem) ?? 0) - 1;
if (next <= 0) freq.delete(rem);
else freq.set(rem, next);
left++;
}
// 3) window [left, right] is valid, update answer
best = Math.max(best, right - left + 1);
}
return best;
}
export { slidingWindow };
/**
* Sliding window (variable length), longest valid window.
* Expand `right`, shrink `left` while the invariant breaks, then record the answer.
*
* Minimum covering window: shrink while still valid, update `best` only when valid
* (often start with `best = Infinity`).
*/
function slidingWindow(s: string): number {
const freq = new Map<string, number>();
let left = 0;
let best = 0;
const windowOk = () => {
// Replace with the problem invariant (e.g. all unique, sum ≤ k).
return true;
};
for (let right = 0; right < s.length; right++) {
// 1) expand: add s[right] into window state
const add = s[right]!;
freq.set(add, (freq.get(add) ?? 0) + 1);
// 2) shrink while the invariant is broken
while (left <= right && !windowOk()) {
const rem = s[left]!;
const next = (freq.get(rem) ?? 0) - 1;
if (next <= 0) freq.delete(rem);
else freq.set(rem, next);
left++;
}
// 3) window [left, right] is valid, update answer
best = Math.max(best, right - left + 1);
}
return best;
}
export { slidingWindow };
- 1#3 Longest Substring Without Repeating CharactersRehbermedium
- 2#76 Minimum Window SubstringRehberhard
- 3#209 Minimum Size Subarray SumRehbermedium
- 4#424 Longest Repeating Character ReplacementRehbermedium
- 5#567 Permutation in StringRehbermedium
- 6#904 Fruit Into BasketsRehbermedium