We are given an array A
of positive integers, and two positive integers L
and R
(L <= R
).
Return the number of (contiguous, non-empty) subarrays such that the value of the maximum array element in that subarray is at least L
and at most R
.
Example : Input: A = [2, 1, 4, 3] L = 2 R = 3 Output: 3 Explanation: There are three subarrays that meet the requirements: [2], [2, 1], [3].
找连续的子数组,要求子数组中最大的数在[L, R]区间内,统计并返回个数。
1、对于>R的点,是子数组的分割点。
2、对于<L的点,可以附着在之前所有符合要求的子数组尾部。
3、对于在[L, R]的点,既可以附着在之前的子数组尾部,也可以从头开始自成一个新数组。
令len表示之前符合要求的子数组长度,且该子数组最后一个数字必须在[L, R]内,因为当出现连续的<L的点,必须合并在一起附着。
对于情况1,重置len = 0
对于情况2,只需要加上len
对于情况3,首先更新len,再加上len
我的答案:
class Solution { public: int numSubarrayBoundedMax(vector<int>& A, int L, int R) { int res = 0; int len = 0; int pos = 0; for (int i=0; i<A.size(); ++i) { if (A[i] > R) { len = 0; pos = i + 1; } else { if (A[i] >= L) { len = i - pos + 1; } res += len; } } return res; } };
后来看了别人的答案,有一种很巧妙的方法,[L, R] = [-∞, R] - [-∞, L-1]
class Solution { public: int numSubarrayBoundedMax(const vector<int>& A, int L, int R) { return helper(A, R) - helper(A, L - 1); } int helper(const vector<int>& a, int value) { int res = 0, c = 0; for (int i : a) { if (i <= value) ++c; else c = 0; res += c; } return res; } };