3113 Find the Number of Subarrays Where Boundary Elements Are Maximum
比赛中一直尝试用monotonically increasing stack + hashmap for counting来做,但一直没写出来,原因就是没有理解好题目,在硬凑. 我们首先明白的是:
- 我们需要一个计数器,记录每一个元素遇到的次数
- 我们需要一个monotonic stack
- 单调递增stack, 则盏顶为最大值
- 单调递减stack, 则盏底为最大值
我们在每次遇见一个curr max时,我们需要清空之前的所有信息,对于[6,26,6]这样的array来说,在遇到26时,之前遇到的6已经没有意义了.

与之对应的,[6,1,6]则可以构成一个符合条件的array. 因此我们的solution必须能处理这两种情况,
# peak
[6,26,6]
# valley
[6,1,6]
单调递增盏不会剔除比最大值小的元素,这是我们选择用单调递增还是递减的关键。同时我们可以把hashmap的功能,直接放在stack中,为什么这样做呢?因为我们只关心当前遇到的这个数num在以前有没有遇到过.
- 建立一个stack, 严格递减
- 维护一个res, 用来记录符合条件的subarray的个数
- 循环nums:
- 常规操作,维护严格单调递减stack
- 如果盏顶元素和新进入元素相等,则更新盏顶元素的计数器,跳过后续操作
- 否则,将新元素加入stack, 并更新res
Approach 1 Monotonic Stack
class Solution:
def numberOfSubarrays(self, nums: List[int]) -> int:
"""
observation:
- count subarray系列题目
- condition: arr[0] arr[-1] are the min and max of the subarray
- nums[i] >= 1, 所以可以用sliding window,也有可能是monotonic queue
- monotically increasing queue (不需要strictly)
intuition:
- monotonically decreasing stack
"""
stack = []
res = 0
for num in nums:
while stack and stack[-1][0] < num:
stack.pop()
if stack and num == stack[-1][0]:
stack[-1][1] += 1
res += stack[-1][1]
continue
stack.append([num,1])
res += stack[-1][1]
return res