2Brute2Best
🔥0
04

At Most / At Least K (counting) (Sliding Window Sub-pattern)

Count how many subarrays satisfy a rule instead of finding the best one. For an at most rule, every start from left to right is valid for the current right end. For an at least rule, it flips: once the window is good, every start before left (or every extension to the right) is good too.

Signals in the problem statement
  • ›

    "count the number of subarrays…"

  • ›

    "product less than k" / "score less than k"

  • ›

    "at most k distinct" + count

  • ›

    "contains at least one of each…" / "appears at least k times"

What makes it different

The answer is a count. At most → add right − left + 1 per step. At least → shrink while the window is still good, then add left (all starts before left work).

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1Medium
  2. 2
    Subarray Product Less Than K
    Basic Reinforcement·LeetCode #713
    Medium
  3. 3Medium
  4. 4Medium
  5. 5
    Count Subarrays With Score Less Than K
    Pattern Transfer·LeetCode #2302
    Hard

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?