大家好,我是开车的阿Q,自动驾驶的时代已经到来,没时间解释了,快和阿Q一起上车。作为自动驾驶系统工程师,必须要有最好的C++基础,让我们来一起刷题吧。

题目考察的知识点

  • 数组遍历与处理
  • 滑动窗口思想
  • 双端队列的应用

题目解答方法的文字分析

题目要求在给定整数数组 heights 和整数 k 的情况下,找到一个合适的地区范围,使得该范围内的高度差不超过 k,并且范围最大。为了解决这个问题,我们采用滑动窗口的思想,并使用双端队列来维护当前窗口内的高度索引。

我们使用两个双端队列 maxDq 和 minDq 分别来维护当前窗口内的高度索引,其中 maxDq 用于找到当前窗口内的最大高度,而 minDq 用于找到当前窗口内的最小高度。

我们同时维护两个指针 left 和 right,表示滑动窗口的左右边界。开始时,两个指针都指向数组的起始位置。

我们不断右移右指针 right,在右移的过程中,维护双端队列 maxDq 和 minDq,使其保持高度索引对应的值递增和递减顺序,并确保队列内的高度差不超过 k。

如果当前窗口内的最大和最小高度的差大于 k,说明当前窗口不满足条件,需要调整左指针 left,使窗口范围变小,直到满足条件。

记录当前合适范围的长度,不断更新最大范围 maxRange。

继续右移右指针 right,重复上述过程,直到右指针遍历完整个数组。

class Solution {
public:
    int findMaxRangeWithinThreshold(vector<int>& heights, int k) {
        deque<int> maxDq; // 有序双端队列,存储当前窗口内的高度索引,队头是最大值的索引
        deque<int> minDq; // 有序双端队列,存储当前窗口内的高度索引,队头是最小值的索引
        int left = 0; // 滑动窗口的左边界
        int maxRange = 0; // 记录最大的合适范围长度

        for (int right = 0; right < heights.size(); ++right) {
            // 维护有序双端队列 maxDq 和 minDq,使其保持高度对应的值递增和递减顺序
            while (!maxDq.empty() && heights[right] >= heights[maxDq.back()]) {
                maxDq.pop_back();
            }
            maxDq.push_back(right);

            while (!minDq.empty() && heights[right] <= heights[minDq.back()]) {
                minDq.pop_back();
            }
            minDq.push_back(right);

            // 如果当前窗口内的最大和最小高度的差大于k,更新左边界left
            while (heights[maxDq.front()] - heights[minDq.front()] > k) {
                ++left;
                if (maxDq.front() < left) {
                    maxDq.pop_front();
                }
                if (minDq.front() < left) {
                    minDq.pop_front();
                }
            }

            // 计算当前合适范围的长度,更新最大范围maxRange
            maxRange = max(maxRange, right - left + 1);
        }

        return maxRange;
    }
};