找出 nums 中连续、非空且其中最大元素在范围 内的子数组,并返回满足条件的子数组的个数。

生成的测试用例保证结果符合 32-bit 整数范围。

输出:3

一个容易想到的思路是使用“单调栈”。

“统计所有最大值范围在 之间的子数组个数,可等价为统计每一个范围落在 之间的 作为最大值时子数组的个数。”

由此可以进一步将问题转换为:求解每个 作为子数组最大值时,最远的合法左右端点的位置。也就是求解每一个 左右最近一个比其“大”的位置,这可以使用“单调栈”来进行求解。

“统计所有 对答案的贡献即是最终答案,但我们忽略了“当 nums 存在重复元素,且该元素作为子数组最大值时,最远左右端点的边界越过重复元素时,导致重复统计子数组”的问题。”

为了消除这种重复统计,我们可以将“最远左右边界”的一端,从“严格小于”调整为“小于等于”,从而实现半开半闭的效果。

除了统计“每个 作为子数组最大值时,所能贡献的子数组个数”以外,我们还可以统计“每个 作为子数组右端点时,所能贡献的子数组个数”。

具体的,我们从前往后处理每个 ,并统计其作为子数组右端点时,所能贡献的子数组个数。遍历过程中根据 与规定范围 之间的关系进行分情况讨论:

大于 , 作为右端点,必不可能贡献合法子数组。小于 ,此时 想作为右端点的话,子数组必须有其他满足“范围落在 之间”的其他数,而最近一个满足要求的位置为 ,若有 ,说明范围在 均能作为子数组的左端点,累加方案数 ;若有 ,说明我们无法找到任何一个左端点,使得形成的子数组满足要求(要么最值不在 范围内,要么有 范围内的数,但最大值又大于 b 值);

落在范围 ,此时 想作为右端点的话,只需要找到左边第一个数值大于 的数值即可(即变量 k),累加方案数 。在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

更多更全更热门的“笔试/面试”相关资料可访问排版精美的 合集新基地 🎉🎉