给你一个整数数组 nums
和两个整数:left
及 right
。找出 nums
中连续、非空且其中最大元素在范围 [left, right]
内的子数组,并返回满足条件的子数组的个数。
生成的测试用例保证结果符合 32-bit 整数范围。
示例 1:
输入: nums = [2,1,4,3], left = 2, right = 3
输出: 3
解释: 满足条件的三个子数组:[2], [2, 1], [3]
示例 2:
输入: nums = [2,9,2,5,6], left = 2, right = 8
输出: 7
提示:
1 <= nums.length <= 105
0 <= nums[i] <= 109
0 <= left <= right <= 109
题解:
/**
* @param {number[]} nums
* @param {number} left
* @param {number} right
* @return {number}
*/
// 方法一:一次遍历
var numSubarrayBoundedMax = function (nums, left, right) {
let res = 0, last2 = -1, last1 = -1;
for (let i = 0; i < nums.length; i++) {
// 当前值满足条件时 last1 等于当前位置
// 否则last2 等于当前位置 last1 值为-1
if (nums[i] >= left && nums[i] <= right) {
last1 = i
} else if (nums[i] > right) {
last2 = i
last1 = -1
}
// 子数组若以 i 为右端点,合法的左端点可以落在(last2, last1]
// 这样的左端点共有last1 - last2个
if (last1 != -1) {
res += last1 - last2
}
}
return res
};
// 方法二:计数
var numSubarrayBoundedMax = function (nums, left, right) {
// count(nums, right) => 获取满足小等于right 的值
// count(nums, left-1) => 获取满足小left 的值
return count(nums, right) - count(nums, left - 1)
}
var count = function (nums, lows) {
let cur = 0, res = 0;
for (let x of nums) {
cur = x <= lows ? cur + 1 : 0
res += cur
}
return res
}