给你一个下标从 0 开始的整数数组 nums
。nums
的一个子数组如果满足以下条件,那么它是 不间断 的:
i
,i + 1
,...,j
表示子数组中的下标。对于所有满足i <= i1, i2 <= j
的下标对,都有0 <= |nums[i1] - nums[i2]| <= 2
。
请你返回 不间断 子数组的总数目。
子数组是一个数组中一段连续 非空 的元素序列。
示例 1:
输入:nums = [5,4,2,4] 输出:8 解释: 大小为 1 的不间断子数组:[5], [4], [2], [4] 。 大小为 2 的不间断子数组:[5,4], [4,2], [2,4] 。 大小为 3 的不间断子数组:[4,2,4] 。 没有大小为 4 的不间断子数组。 不间断子数组的总数目为 4 + 3 + 1 = 8 。 除了这些以外,没有别的不间断子数组。
示例 2:
输入:nums = [1,2,3] 输出:6 解释: 大小为 1 的不间断子数组:[1], [2], [3] 。 大小为 2 的不间断子数组:[1,2], [2,3] 。 大小为 3 的不间断子数组:[1,2,3] 。 不间断子数组的总数目为 3 + 2 + 1 = 6 。
提示:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
提示 1
Try using the sliding window technique.
提示 2
Use a set or map to keep track of the maximum and minimum of subarrays.
解法: 双指针+不定长滑动窗口
相似题目:
LeetCode 2537. 统计好子数组的数目-CSDN博客 (同为 不定长滑动窗口 求子数组数组)
LeetCode 1438. 绝对差不超过限制的最长连续子数组-CSDN博客 ()
class Solution {
public long continuousSubarrays(int[] nums) {
long ans = 0;
TreeMap<Integer, Integer> window = new TreeMap<>();
int left = 0;
int right = 0;
while (right < nums.length) {
window.merge(nums[right], 1, Integer::sum);
while (window.lastKey() - window.firstKey() > 2) {
if (window.merge(nums[left], -1, Integer::sum) == 0) {
window.remove(nums[left]);
}
left++;
}
ans += right - left + 1;
right++;
}
return ans;
}
}
复杂度分析
- 时间复杂度:O(n),n 是 数组 nums 的长度。
- 空间复杂度:O(1),最坏情况下 window 的长度为3。