leetcode 中国区开放了,传送门
该问题地址:点我去看看
问题描述
给定一个元素都是正整数的数组A
,正整数 L
以及 R
(L <= R
)。
求连续、非空且其中最大元素满足大于等于L
小于等于R
的子数组个数。
例如 :
输入:
A = [2, 1, 4, 3]
L = 2
R = 3
输出: 3
解释: 满足条件的子数组: [2], [2, 1], [3].
解题思路
根据条件 L
与 R
,可以把数字分为三种,分别是 <L
,>=L 且 <=R
以及 > R
。其中 >R
的数据不可能存在与符合条件(最大元素在 L R
之间)的子数组中,所以可以把 >R
的数据看做一堵墙,所有的子数组不可能越过墙。
我们先考虑没有墙的情况。
假设L R
分别是2 3
。
假设给定数组[1,1,2,1,1]
。(为了简化问题,1
代表<L
的数,2
代表>=L 且 <=R
的数)
初始数量 c = 0
。
遍历数组,遇到前两个1
时,数量依然为0
,当遇到2时,符合条件的子数组有[1,1,2],[1,2],[2]
,数量为3
,与2
的处于低三个位置相对应。此时 c=3
。
当遇到2
后面的1
时,新增的符合条件子数组有[1,1,2,1][1,2,1][2,1]
。
当遇到最后一个1
是,新增的符合条件子数组有[1,1,2,1,1][1,2,1,1][2,1,1]
。
新增的数量也与上一个2
的位置有关。
再看个复杂点的例子。比如[1,2,1,2,1,1]
。
当遍历到最后一个1
时,新增的数组为[1,2,1,2,1,1] [2,1,2,1,1] [1,2,1,1] [2,1,1]
。
该数量与最后遇到的 2
的位置有关。
数组中存在墙的时候,可以看做墙把数组分成一个个子数组,在各个子数组中求子数组个数,最后加一起即可。
js代码实现
var numSubarrayBoundedMax = function(A, L, R) {
var c_length = 0; // 记录当前子数组遍历到哪个位置
var c_last_key_length = 0; // 记录上一次遇到的 >=L 且 <=R 的数字位置
var c_sum = 0; // 记录被墙分开的每段子数组的总和
var sum = 0; // 记录总和
A.forEach(function(e){
if (e > R){
sum += c_sum;
c_length = 0;
c_last_key_length = 0;
c_sum = 0;
}else if (e < L){
c_length ++;
c_sum = c_sum + c_last_key_length;
} else{
c_length ++;
c_last_key_length = c_length;
c_sum += c_length;
}
});
sum += c_sum;
return sum;
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。