05
Exactly K (Sliding Window Sub-pattern)
Count subarrays with exactly K of something. Direct windows fail, so compute atMost(K) − atMost(K − 1).
Signals in the problem statement
- ›
"exactly k distinct"
- ›
"exactly k odd numbers"
- ›
"sum equals goal" on a 0/1 array
What makes it different
Not monotonic on its own. Turning it into two monotonic counts is the whole trick.
Questions
ordered from “learn the idea” to “recognise it without help”- 1Binary Subarrays With SumWalkthroughMediumBasic Anchor·LeetCode #930
- 2Count Number of Nice SubarraysWalkthroughMediumBasic Reinforcement·LeetCode #1248
- 3Subarrays with K Different IntegersWalkthroughHardSlight Variation·LeetCode #992
- 4Count Subarrays With Fixed BoundsWalkthroughHardTricky / Edge Case·LeetCode #2444
Template
atmost-template.cpp
// Count subarrays satisfying an "at most" rule.
// For a fixed right end, every start in [left..right] is valid.
long long countAtMost(vector<int>& a, int k) {
if (k < 0) return 0; // "at most -1" is impossible (use k <= 0 for distinct counts)
long long count = 0;
int left = 0;
for (int right = 0; right < (int)a.size(); right++) {
add(a[right]);
while (!valid(k)) { remove(a[left]); left++; }
count += right - left + 1; // subarrays ending at right
}
return count;
}
// "Exactly K" is not monotonic, so use two "at most" counts:
long long countExactly(vector<int>& a, int k) {
return countAtMost(a, k) - countAtMost(a, k - 1);
}Remember this · Sliding Window
Trigger
Contiguous subarray / substring + longest, shortest, maximum, count, or "of size K".
Think
Can I keep a valid range and move it, instead of checking every subarray from scratch?
Key question
When is my current window valid?