# 3113. Find the Number of Subarrays Where Boundary Elements Are Maximum

## Description

You are given an array of positive integers nums.

Return the number of subarrays of nums, where the first and the last elements of the subarray are equal to the largest element in the subarray.

Example 1:

Input: nums = [1,4,3,3,2]

Output: 6

Explanation:

There are 6 subarrays which have the first and the last elements equal to the largest element of the subarray:

• subarray [1,4,3,3,2], with its largest element 1. The first element is 1 and the last element is also 1.
• subarray [1,4,3,3,2], with its largest element 4. The first element is 4 and the last element is also 4.
• subarray [1,4,3,3,2], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [1,4,3,3,2], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [1,4,3,3,2], with its largest element 2. The first element is 2 and the last element is also 2.
• subarray [1,4,3,3,2], with its largest element 3. The first element is 3 and the last element is also 3.

Hence, we return 6.

Example 2:

Input: nums = [3,3,3]

Output: 6

Explanation:

There are 6 subarrays which have the first and the last elements equal to the largest element of the subarray:

• subarray [3,3,3], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [3,3,3], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [3,3,3], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [3,3,3], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [3,3,3], with its largest element 3. The first element is 3 and the last element is also 3.
• subarray [3,3,3], with its largest element 3. The first element is 3 and the last element is also 3.

Hence, we return 6.

Example 3:

Input: nums = [1]

Output: 1

Explanation:

There is a single subarray of nums which is [1], with its largest element 1. The first element is 1 and the last element is also 1.

Hence, we return 1.

Constraints:

• 1 <= nums.length <= 105
• 1 <= nums[i] <= 109

## Solutions

### Solution 1: Monotonic Stack

We consider each element $x$ in the array $nums$ as the boundary element and the maximum value of the subarray.

Each subarray of length $1$ meets the condition, and for subarrays with length greater than $1$, all elements in the subarray cannot be greater than the boundary element $x$. We can implement this with a monotonic stack.

We maintain a stack that decreases monotonically from the bottom to the top. Each element in the monotonic stack is a pair $[x, cnt]$, representing the element $x$ and the count $cnt$ of subarrays with $x$ as the boundary element and the maximum value.

We traverse the array $nums$ from left to right. For each element $x$, we continuously pop the top element of the stack until the stack is empty or the first element of the top element of the stack is greater than or equal to $x$. If the stack is empty, or the first element of the top element of the stack is greater than $x$, it means that we have encountered the first subarray with $x$ as the boundary element and the maximum value, and the length of this subarray is $1$, so we push $[x, 1]$ into the stack. If the first element of the top element of the stack is equal to $x$, it means that we have encountered a subarray with $x$ as the boundary element and the maximum value, and we add $1$ to the second element of the top element of the stack. Then, we add the second element of the top element of the stack to the answer.

After the traversal, we return the answer.

The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $nums$.

• class Solution {
public long numberOfSubarrays(int[] nums) {
Deque<int[]> stk = new ArrayDeque<>();
long ans = 0;
for (int x : nums) {
while (!stk.isEmpty() && stk.peek()[0] < x) {
stk.pop();
}
if (stk.isEmpty() || stk.peek()[0] > x) {
stk.push(new int[] {x, 1});
} else {
stk.peek()[1]++;
}
ans += stk.peek()[1];
}
return ans;
}
}

• class Solution {
public:
long long numberOfSubarrays(vector<int>& nums) {
vector<pair<int, int>> stk;
long long ans = 0;
for (int x : nums) {
while (!stk.empty() && stk.back().first < x) {
stk.pop_back();
}
if (stk.empty() || stk.back().first > x) {
stk.push_back(make_pair(x, 1));
} else {
stk.back().second++;
}
ans += stk.back().second;
}
return ans;
}
};

• class Solution:
def numberOfSubarrays(self, nums: List[int]) -> int:
stk = []
ans = 0
for x in nums:
while stk and stk[-1][0] < x:
stk.pop()
if not stk or stk[-1][0] > x:
stk.append([x, 1])
else:
stk[-1][1] += 1
ans += stk[-1][1]
return ans


• func numberOfSubarrays(nums []int) (ans int64) {
stk := [][2]int{}
for _, x := range nums {
for len(stk) > 0 && stk[len(stk)-1][0] < x {
stk = stk[:len(stk)-1]
}
if len(stk) == 0 || stk[len(stk)-1][0] > x {
stk = append(stk, [2]int{x, 1})
} else {
stk[len(stk)-1][1]++
}
ans += int64(stk[len(stk)-1][1])
}
return
}

• function numberOfSubarrays(nums: number[]): number {
const stk: number[][] = [];
let ans = 0;
for (const x of nums) {
while (stk.length > 0 && stk.at(-1)![0] < x) {
stk.pop();
}
if (stk.length === 0 || stk.at(-1)![0] > x) {
stk.push([x, 1]);
} else {
stk.at(-1)![1]++;
}
ans += stk.at(-1)![1];
}
return ans;
}