Skip to main content

2444. Bounded Subarrays

Count Subarrays With Fixed Bounds

Excellent problem to enhance sliding window technique.

Since We Need Both minK and maxK to Be Bounded

Each time we move window's right end rightIdx, first check whether

minKnums[rightIdx]maxKminK \leq nums[rightIdx] \leq maxK.

If not, nums[rightIdx]nums[rightIdx] falls outside valid range, so no valid subarray with rightIdx as the right end can exist.

Directly reset window's left end leftIdx to rightIdx + 1, and also reset both prevMinIdx and prevMaxIdx to -1,

since we don't yet know whether nums[leftIdx:]nums[leftIdx:] contains elements equal to minKminK or maxKmaxK.

As Long as nums[leftIdx:rightIdx+1]nums[leftIdx: rightIdx + 1] Stay Fully In Bounds

We look within window for:

the most recent index ii where nums[i]=minKnums[i] = minK, and assign it to prevMinIdx;

the most recent index jj where nums[j]=maxKnums[j] = maxK, and assign it to prevMaxIdx.

Once both prevMinIdx and prevMaxIdx are not -1, our window has just satisfied the problem's requirements.

Valid subarrays within this window must satisfy three conditions:

(1). Right end exactly at rightIdx

(2). Left end at least at leftIdx, while not exceeding right end

(3). Left end at most at min(prevMinIdx, prevMaxIdx)

(1) and (2) are intuitive. The key is where (3) comes from.

If some index kk in the window satisfies min(prevMinIdx, prevMaxIdx) <k< k,

then nums[k:rightIdx+1]nums[k:rightIdx + 1] can't contain both minKminK and maxKmaxK.

Each bounded subarray is required to contain both minKminK and maxKmaxK.

Therefore, number of valid subarrays in current window is:

C=C = min(prevMinIdx, prevMaxIdx) + 1 - leftIdx

Add CC to boundedSubarraysCount, which will be returned at the end.

#include <vector>
using namespace std;

long long countBoundedSubarrays(vector<int>& nums, int minK, int maxK) { // LeetCode Q.2444.
long long boundedSubarraysCount = 0;

int prevMinIdx = -1, prevMaxIdx = -1;

int leftIdx = 0;
for (int rightIdx = 0; rightIdx < nums.size(); rightIdx++) {
int num = nums[rightIdx];

if (num < minK || num > maxK) { // Reset.
prevMinIdx = -1, prevMaxIdx = -1;
leftIdx = rightIdx + 1;
continue;
}

if (num == maxK)
prevMaxIdx = rightIdx;
if (num == minK)
prevMinIdx = rightIdx;

if (min(prevMinIdx, prevMaxIdx) >= 0)
boundedSubarraysCount += min(prevMinIdx, prevMaxIdx) + 1 - leftIdx;
}

return boundedSubarraysCount;
}

Sliding Window Efficiency Time complexity is O(n)O(n) where nn is input array length. Space is O(1)O(1): just four pointers and boundedSubarraysCount to track total.