题目
给你一个下标从 0 开始的整数数组 nums 。nums 的一个子数组如果满足以下条件,那么它是 不间断 的:
- i,i + 1 ,…,j 表示子数组中的下标。对于所有满足 i <= i1, i2 <= j 的下标对,都有 0 <= |nums[i1] - nums[i2]| <= 2 。
请你返回 不间断 子数组的总数目。
子数组是一个数组中一段连续 非空 的元素序列。
思路
双指针+有序集合
在遍历数组的同时,用多重集合维护窗口内的数字。
如果窗口内的最大值与最小值的差大于 2,就不断移动左端点 left,减少窗口内的数字。
最后 [left,right],[left+1,right],⋯,[right,right]
这一共 right−left+1
个子数组都是合法的,加入答案。
long long continuousSubarrays(vector<int>& nums) {
long long sum=0; // 统计数目
int left=0,right=0;
multiset<int> s; //保存子数组的数,方便寻找最大值和最小值
while(right < nums.size()){
s.insert(nums[right]); // 将右端点加入子数组
while (*s.rbegin() - *s.begin() > 2) { // 如果当前子数组不满足差小于等于2 ,将左端点弹出,并统计合法子数组个数
s.erase(s.find(nums[left++]));
sum += right-left+1;
}
right++;
}
// 统计剩下合法子数组的个数
int n=right-left;
while(n>0){
sum+=n;
--n;
}
return sum;
}