Opening the reading…
Opening the reading…
SLIDING WINDOW › FIXED SIZE SLIDING-WINDOW
Open — the attempt gate is not wired up yet
This editorial is meant to unlock after you have run the problem at least once, with the worked solution behind one further deliberate click. That needs per-learner unlock state nothing stores today, so for now the whole article is open.
Try it yourself first →Two strings are anagrams when every letter appears the same number of times in both strings. The order of those letters does not matter, so checking every permutation is unnecessary. For p, build a frequency count for the 26 lowercase letters; any window in s is an anagram precisely when its count matches that vector.
Every candidate window must have the same length as p. Start with the first window, then move its right edge one position at a time. Each move adds one entering character and removes one leaving character, so the counts stay accurate without recounting the whole window. Once a full window exists, compare its 26 counts and record its start when they match.
| MEASURE | BOUND | WHY |
|---|---|---|
| Time | O(n) | Each character of s is added once and, after the first full window, removed once. Each full window compares 26 counters, which is constant because the alphabet is fixed, so the total work remains proportional to n even in the worst case. |
| Space | O(1) extra | The two frequency arrays always contain 26 integers, regardless of n or m. The returned index array is required output and is excluded; there is no degradation for any input shape because the working arrays never grow with the strings. |
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> result;
int n = static_cast<int>(s.size());
int m = static_cast<int>(p.size());
if (n < m) return result;
vector<int> target(26, 0);
vector<int> window(26, 0);
for (char c : p) {
target[c - 'a']++;
}
for (int i = 0; i < n; i++) {
window[s[i] - 'a']++;
if (i >= m) {
window[s[i - m] - 'a']--;
}
if (i >= m - 1 && window == target) {
result.push_back(i - m + 1);
}
}
return result;
}
};The order of the update and test is the central detail. Adding s[i] first makes the new right endpoint part of the window. Removing s[i - m] when it exists then restores the exact length m. The test comes after both updates, so window contains precisely the characters from i - m + 1 through i, and that start index is computed from the same endpoint.