leetcode 中国区开放了, 传送门
该问题地址:点我去看看数组
给定一个元素都是正整数的数组A
,正整数 L
以及 R
(L <= R
)。code
求连续、非空且其中最大元素知足大于等于L
小于等于R
的子数组个数。ip
例如 : 输入: A = [2, 1, 4, 3] L = 2 R = 3 输出: 3 解释: 知足条件的子数组: [2], [2, 1], [3].
根据条件 L
与 R
,能够把数字分为三种,分别是 <L
,>=L 且 <=R
以及 > R
。其中 >R
的数据不可能存在与符合条件(最大元素在 L R
之间)的子数组中,因此能够把 >R
的数据看作一堵墙,全部的子数组不可能越过墙。leetcode
咱们先考虑没有墙的状况。get
假设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
。it
当遇到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
的位置有关。io
再看个复杂点的例子。好比[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
的位置有关。ast
数组中存在墙的时候,能够看作墙把数组分红一个个子数组,在各个子数组中求子数组个数,最后加一块儿便可。function
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; };