📜  门|门CS 2008 |第 84 题(1)

📅  最后修改于: 2023-12-03 14:58:36.846000             🧑  作者: Mango

题目介绍

本题为"门"问题,即求一个序列中长度大于等于m的连续子序列,使得子序列中的最大值与最小值之差不超过k。

本题为计算机科学及技术专业研究生入学考试(CS)的题目,是一道经典的算法题目,解题需要运用数据结构和算法知识。

解题思路

此题可以用单调队列(deque)求解。

我们从序列的头开始扫描,假设当前位置为i。

  1. 首先我们需要判断当前单调队列中的最小值和最大值是否满足条件,即 max(queue) - min(queue) <= k,如果满足则计算长度是否大于等于m,如果满足则更新答案。然后我们需要将队首的数弹出,直到当前队列中的最小值和最大值符合条件。

  2. 将i加入单调队列中,并且保持队列单调不降。我们只需要将队列中比i小的数全部弹出即可。

  3. 重复以上步骤。

最后的答案即为所求。

时间复杂度为 O(N)。

代码实现

def sliding_window(nums, k, m):
    ans = 0

    # 初始化队列
    q_min, q_max = deque(), deque()
    for i in range(len(nums)):
        # 让队列单调不降
        while q_min and nums[q_min[-1]] > nums[i]:
            q_min.pop()
        q_min.append(i)
        while q_max and nums[q_max[-1]] < nums[i]:
            q_max.pop()
        q_max.append(i)

        # 判断队列是否符合条件
        while q_max and q_min and nums[q_max[0]] - nums[q_min[0]] > k:
            if q_max[0] > q_min[0]:
                j = q_min.popleft() + 1
            else:
                j = q_max.popleft() + 1

        # 判断是否计算答案
        if q_max and q_min and q_max[0] - q_min[0] + 1 >= m:
            ans = max(ans, nums[q_max[0]] - nums[q_min[0]])

    return ans

以上就是本题的详细介绍及解题思路和代码实现。