LeetCode 2762. Continuous Subarrays

96 阅读1分钟

🔗 leetcode.com/problems/co…

题目

  • 给一个 int 组成的数组

  • 返回满足以下条件的子数组的个数

    • 子数组内的任意两个数字的差小于等于 2

思路

  • 滑动窗口 + 单调队列
  • 定义一个严格单调递增的队列,记录区间 min
  • 定义一个严格单调递减的队列,记录区间 max
  • 固定 left,滑动 right,找到满足要求的子数组,此时可以满足条件的子数组个数为 right - left + 1
  • 遍历固定 left 的起始位置,进行统计

代码

class Solution {
public:
    long long continuousSubarrays(vector<int>& nums) {
        int n = nums.size();
        long long ans = 0;
        
        deque<pair<int, int>> min_dq, max_dq;
        min_dq.push_back(make_pair(nums[0], 0));
        max_dq.push_back(make_pair(nums[0], 0));

        int j = 0;
        for (int i = 0; i < n; i++) {
            while (min_dq.front().second < i) {
                min_dq.pop_front();
            }
            int mi_num = min_dq.front().first;

            while (max_dq.front().second < i) {
                max_dq.pop_front();
            }
            int ma_num = max_dq.front().first;
            
            if (j == n) {
                if (ma_num - mi_num <= 2) {
                    ans += j - i;
                }
                continue;
            }

            while (ma_num - mi_num <= 2) {
                j++;
                if (j == n) break;
                // update min dq
                while (min_dq.empty() == false && min_dq.back().first >= nums[j]) min_dq.pop_back();
                min_dq.push_back(make_pair(nums[j], j));

                // update max dq
                while (max_dq.empty() == false && max_dq.back().first <= nums[j]) max_dq.pop_back();
                max_dq.push_back(make_pair(nums[j], j));

                mi_num = min_dq.front().first;
                ma_num = max_dq.front().first;
            }

            ans += j - i;
        }

        return ans;
    }
};