题目
题解
注意题目中说的是 子数组的最大值在 [left,right] 区间就行,翻译一下就是子数组中不能有超过right的元素,且至少有一个元素在 [left,right] 区间内
一次遍历
维护两个变量
last1:目标区间元素最后一次出现的位置
last2:非目标区间元素最后一次出现的位置
如果last1存在,则结果+=last1-last2
class Solution {
public int numSubarrayBoundedMax(int[] nums, int left, int right) {
int n=nums.length,res=0,last1=-1,last2=-1;
for(int i=0;i<n;i++){
if(nums[i]>=left&&nums[i]<=right)
last1=i;//目标区间元素最后一次出现的位置
else if(nums[i]>right){
last2=i;//非目标区间元素最后一次出现的位置
last1=-1;//标记此轮跳过res更新
}
if(last1!=-1)
res+=last1-last2;
}
return res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
计数
[…,right]-[…,left-1],两个区间元素个数相减,得到[left,right]区间的元素个数
class Solution {
public int numSubarrayBoundedMax(int[] nums, int left, int right) {
return count(nums,right)-count(nums,left-1);
}
public int count(int[] nums,int lower){
int cur=0,res=0;
for(int x:nums){
cur=x<=lower?cur+1:0;//i左侧有多少个连续的元素<=lower
res+=cur;
}
return res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)