Given an integer array arr[] and two integers l and r. The task is to find the count of subarrays where the maximum element in that subarray is in range [l, r]. In other words, the max element is at least l and at most r.
Examples:
Input: arr[] = [1, 2, 3, 4, 5], l = 2, r = 5
Output: 11
Explanation: Valid subarrays are: [2], [3], [4], [5], [1,2], [2,3], [3,4], [4,5], [1,2,3], [2,3,4], [3,4,5], [1,2,3,4], [2,3,4,5], [1,2,3,4,5].Input: arr[] = [3, 1, 6, 4], l = 3, r = 6
Output: 9
Explanation: Valid subarrays are: [3], [6], [4], [3,1], [1,6], [6,4], [3,1,6], [1,6,4], [3,1,6,4].Input: arr[] = [1, 2, 3, 4], l = 5, r = 7
Output: 0
Explanation: There is no subarray where the maximum element is at least 5 and at most 7.
Table of Content
[Naive Approach] Generate All Subarrays - O(n^2) Time and O(n) Space
The idea is to generate all subarrays and determine the maximum element in each. By iterating over all starting and ending indices, we keep track of the max value and check if it falls within the range [l, r].
// C++ program to count subarrays where the maximum
// element is at least l and at most r by
// Generating all Subarrays
#include <bits/stdc++.h>
using namespace std;
int countSubarrays(vector<int>& arr,
int l, int r) {
int n = arr.size();
int count = 0;
// Iterate over all possible starting
// points of subarrays
for (int i = 0; i < n; i++) {
int maxVal = arr[i];
// Iterate over all possible ending
// points of subarrays
for (int j = i; j < n; j++) {
// Update maximum element in the
// current subarray
maxVal = max(maxVal, arr[j]);
// Check if maxVal is within the
// given range
if (maxVal >= l && maxVal <= r) {
count++;
}
}
}
return count;
}
// Driver Code
int main() {
vector<int> arr = {1, 2, 3, 4, 5};
int l = 2, r = 5;
cout << countSubarrays(arr, l, r) << endl;
return 0;
}
// Java program to count subarrays where the maximum
// element is at least l and at most r by
// Generating all Subarrays
import java.util.*;
class GfG {
static int countSubarrays(int[] arr, int l, int r) {
int n = arr.length;
int count = 0;
// Iterate over all possible starting
// points of subarrays
for (int i = 0; i < n; i++) {
int maxVal = arr[i];
// Iterate over all possible ending
// points of subarrays
for (int j = i; j < n; j++) {
// Update maximum element in the
// current subarray
maxVal = Math.max(maxVal, arr[j]);
// Check if maxVal is within the
// given range
if (maxVal >= l && maxVal <= r) {
count++;
}
}
}
return count;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int l = 2, r = 5;
System.out.println(countSubarrays(arr, l, r));
}
}
# Python program to count subarrays where the maximum
# element is at least l and at most r by
# Generating all Subarrays
def countSubarrays(arr, l, r):
n = len(arr)
count = 0
# Iterate over all possible starting
# points of subarrays
for i in range(n):
maxVal = arr[i]
# Iterate over all possible ending
# points of subarrays
for j in range(i, n):
# Update maximum element in the
# current subarray
maxVal = max(maxVal, arr[j])
# Check if maxVal is within the
# given range
if maxVal >= l and maxVal <= r:
count += 1
return count
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5]
l, r = 2, 5
print(countSubarrays(arr, l, r))
// C# program to count subarrays where the maximum
// element is at least l and at most r by
// Generating all Subarrays
using System;
class GfG {
static int countSubarrays(int[] arr, int l, int r) {
int n = arr.Length;
int count = 0;
// Iterate over all possible starting
// points of subarrays
for (int i = 0; i < n; i++) {
int maxVal = arr[i];
// Iterate over all possible ending
// points of subarrays
for (int j = i; j < n; j++) {
// Update maximum element in the
// current subarray
maxVal = Math.Max(maxVal, arr[j]);
// Check if maxVal is within the
// given range
if (maxVal >= l && maxVal <= r) {
count++;
}
}
}
return count;
}
// Driver Code
public static void Main() {
int[] arr = {1, 2, 3, 4, 5};
int l = 2, r = 5;
Console.WriteLine(countSubarrays(arr, l, r));
}
}
// JavaScript program to count subarrays where the maximum
// element is at least l and at most r by
// Generating all Subarrays
function countSubarrays(arr, l, r) {
let n = arr.length;
let count = 0;
// Iterate over all possible starting
// points of subarrays
for (let i = 0; i < n; i++) {
let maxVal = arr[i];
// Iterate over all possible ending
// points of subarrays
for (let j = i; j < n; j++) {
// Update maximum element in the
// current subarray
maxVal = Math.max(maxVal, arr[j]);
// Check if maxVal is within the
// given range
if (maxVal >= l && maxVal <= r) {
count++;
}
}
}
return count;
}
// Driver Code
let arr = [1, 2, 3, 4, 5];
let l = 2, r = 5;
console.log(countSubarrays(arr, l, r));
Output
14
[Expected Approach] Using Two Pointers - O(n) Time and O(1) Space
The idea is to efficiently count subarrays where the maximum element falls within the given range. Instead of checking all subarrays, we use a two-pointer approach to track valid subarrays in a single pass. When encountering an element greater than the upper bound, we reset our tracking, while elements within range help extend valid subarrays. This eliminates redundant checks, optimizing the process to linear time complexity.
Steps to implement the above idea:
- Initialize variables count, lastInvalid, and lastValid to track valid subarrays and handle elements outside the range efficiently.
- Iterate through the array while updating lastInvalid when encountering an element greater than the upper bound r.
- Update lastValid whenever an element falls within the range l to r, marking the latest valid position.
- Compute the number of valid subarrays ending at the current index by subtracting lastInvalid from lastValid.
- Accumulate this count into the total count, ensuring all valid subarrays are considered efficiently.
- Continue processing until the entire array is traversed and return the final count.
// C++ program to count subarrays where
// the maximum element is at least l and
// at most r using Two Pointer
#include <bits/stdc++.h>
using namespace std;
int countSubarrays(vector<int>& arr,
int l, int r) {
int n = arr.size();
int count = 0;
int lastInvalid = -1, lastValid = -1;
// Traverse the array once
for (int i = 0; i < n; i++) {
// If arr[i] is out of range,
// reset lastValid
if (arr[i] > r) {
lastInvalid = i;
lastValid = -1;
}
// If arr[i] is within range,
// update lastValid
if (arr[i] >= l && arr[i] <= r) {
lastValid = i;
}
// Add valid subarrays ending at index i
if (lastValid != -1) {
count += lastValid - lastInvalid;
}
}
return count;
}
// Driver Code
int main() {
vector<int> arr = {1, 2, 3, 4, 5};
int l = 2, r = 5;
cout << countSubarrays(arr, l, r) << endl;
return 0;
}
// Java program to count subarrays where
// the maximum element is at least l and
// at most r using Two Pointer
import java.util.*;
class GfG {
static int countSubarrays(int[] arr, int l, int r) {
int n = arr.length;
int count = 0;
int lastInvalid = -1, lastValid = -1;
// Traverse the array once
for (int i = 0; i < n; i++) {
// If arr[i] is out of range,
// reset lastValid
if (arr[i] > r) {
lastInvalid = i;
lastValid = -1;
}
// If arr[i] is within range,
// update lastValid
if (arr[i] >= l && arr[i] <= r) {
lastValid = i;
}
// Add valid subarrays ending at index i
if (lastValid != -1) {
count += lastValid - lastInvalid;
}
}
return count;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
int l = 2, r = 5;
System.out.println(countSubarrays(arr, l, r));
}
}
# Python program to count subarrays where
# the maximum element is at least l and
# at most r using Two Pointer
def countSubarrays(arr, l, r):
n = len(arr)
count = 0
lastInvalid = -1
lastValid = -1
# Traverse the array once
for i in range(n):
# If arr[i] is out of range,
# reset lastValid
if arr[i] > r:
lastInvalid = i
lastValid = -1
# If arr[i] is within range,
# update lastValid
if l <= arr[i] <= r:
lastValid = i
# Add valid subarrays ending at index i
if lastValid != -1:
count += lastValid - lastInvalid
return count
# Driver Code
if __name__ == "__main__":
arr = [1, 2, 3, 4, 5]
l, r = 2, 5
print(countSubarrays(arr, l, r))
// C# program to count subarrays where
// the maximum element is at least l and
// at most r using Two Pointer
using System;
class GfG {
static int countSubarrays(int[] arr, int l, int r) {
int n = arr.Length;
int count = 0;
int lastInvalid = -1, lastValid = -1;
// Traverse the array once
for (int i = 0; i < n; i++) {
// If arr[i] is out of range,
// reset lastValid
if (arr[i] > r) {
lastInvalid = i;
lastValid = -1;
}
// If arr[i] is within range,
// update lastValid
if (arr[i] >= l && arr[i] <= r) {
lastValid = i;
}
// Add valid subarrays ending at index i
if (lastValid != -1) {
count += lastValid - lastInvalid;
}
}
return count;
}
// Driver Code
public static void Main() {
int[] arr = {1, 2, 3, 4, 5};
int l = 2, r = 5;
Console.WriteLine(countSubarrays(arr, l, r));
}
}
// JavaScript program to count subarrays where
// the maximum element is at least l and
// at most r using Two Pointer
function countSubarrays(arr, l, r) {
let n = arr.length;
let count = 0;
let lastInvalid = -1, lastValid = -1;
// Traverse the array once
for (let i = 0; i < n; i++) {
// If arr[i] is out of range,
// reset lastValid
if (arr[i] > r) {
lastInvalid = i;
lastValid = -1;
}
// If arr[i] is within range,
// update lastValid
if (arr[i] >= l && arr[i] <= r) {
lastValid = i;
}
// Add valid subarrays ending at index i
if (lastValid !== -1) {
count += lastValid - lastInvalid;
}
}
return count;
}
// Driver Code
let arr = [1, 2, 3, 4, 5];
let l = 2, r = 5;
console.log(countSubarrays(arr, l, r));
Output
14