🧠
Alternative Optimal Approach (Count Subarrays with Max ≤ right and Subtract Those with Max < left)
💡 This approach uses the principle of inclusion-exclusion by counting subarrays with max ≤ right and subtracting those with max < left, leveraging a helper function for counting.
Intuition
Count all subarrays where max ≤ right, then subtract subarrays where max < left, leaving subarrays where max is in [left, right].
Algorithm
- Define a helper function countAtMost(bound) that counts subarrays with max ≤ bound.
- Compute countRight = countAtMost(right).
- Compute countLeft = countAtMost(left - 1).
- Return countRight - countLeft.
💡 The helper function counts valid subarrays by tracking stretches of elements ≤ bound, then difference isolates subarrays with max in [left, right].
def countAtMost(nums, bound):
count = 0
length = 0
for num in nums:
if num <= bound:
length += 1
count += length
else:
length = 0
return count
def numSubarrayBoundedMax(nums, left, right):
return countAtMost(nums, right) - countAtMost(nums, left - 1)
# Driver code
if __name__ == '__main__':
print(numSubarrayBoundedMax([2,1,4,3], 2, 3)) # Output: 3
Line Notes
def countAtMost(nums, bound):Helper counts subarrays with max ≤ bound
length = 0Tracks current length of valid subarray segment
if num <= bound: length += 1Extend current valid segment if element ≤ bound
count += lengthAdd number of new subarrays ending at current element
else: length = 0Reset length when element exceeds bound
return countReturn total count of valid subarrays
return countAtMost(nums, right) - countAtMost(nums, left - 1)Difference gives count of subarrays with max in [left, right]
public class Solution {
private static int countAtMost(int[] nums, int bound) {
int count = 0, length = 0;
for (int num : nums) {
if (num <= bound) {
length++;
count += length;
} else {
length = 0;
}
}
return count;
}
public static int numSubarrayBoundedMax(int[] nums, int left, int right) {
return countAtMost(nums, right) - countAtMost(nums, left - 1);
}
public static void main(String[] args) {
System.out.println(numSubarrayBoundedMax(new int[]{2,1,4,3}, 2, 3)); // 3
}
}
Line Notes
int count = 0, length = 0;Initialize counters for valid subarrays and current segment length
for (int num : nums)Iterate over array elements
if (num <= bound)Check if element fits bound to extend segment
length++; count += length;Extend segment and add new subarrays ending here
else length = 0;Reset segment length if element too large
return count;Return total count of valid subarrays
return countAtMost(nums, right) - countAtMost(nums, left - 1);Subtract counts to isolate subarrays with max in [left, right]
#include <iostream>
#include <vector>
using namespace std;
int countAtMost(const vector<int>& nums, int bound) {
int count = 0, length = 0;
for (int num : nums) {
if (num <= bound) {
length++;
count += length;
} else {
length = 0;
}
}
return count;
}
int numSubarrayBoundedMax(vector<int>& nums, int left, int right) {
return countAtMost(nums, right) - countAtMost(nums, left - 1);
}
int main() {
vector<int> nums = {2,1,4,3};
cout << numSubarrayBoundedMax(nums, 2, 3) << endl; // 3
return 0;
}
Line Notes
int count = 0, length = 0;Initialize counters for valid subarrays and segment length
for (int num : nums)Iterate over elements
if (num <= bound)Check if element fits bound to extend segment
length++; count += length;Extend segment and add new subarrays ending here
else length = 0;Reset segment length if element too large
return count;Return total count of valid subarrays
return countAtMost(nums, right) - countAtMost(nums, left - 1);Subtract counts to isolate subarrays with max in [left, right]
function countAtMost(nums, bound) {
let count = 0, length = 0;
for (const num of nums) {
if (num <= bound) {
length++;
count += length;
} else {
length = 0;
}
}
return count;
}
function numSubarrayBoundedMax(nums, left, right) {
return countAtMost(nums, right) - countAtMost(nums, left - 1);
}
// Test
console.log(numSubarrayBoundedMax([2,1,4,3], 2, 3)); // 3
Line Notes
let count = 0, length = 0;Initialize counters for valid subarrays and segment length
for (const num of nums)Iterate over array elements
if (num <= bound)Check if element fits bound to extend segment
length++; count += length;Extend segment and add new subarrays ending here
else length = 0;Reset segment length if element too large
return count;Return total count of valid subarrays
return countAtMost(nums, right) - countAtMost(nums, left - 1);Subtract counts to isolate subarrays with max in [left, right]
Two passes through the array with constant extra space, counting subarrays efficiently.
💡 For n=10^5, this approach is very efficient and easy to implement.
Interview Verdict: Accepted
This approach is elegant and optimal, showing mastery of problem decomposition and counting techniques.