子数组和的最大值问题

100 阅读3分钟

子数组和的最大值问题

问题描述

小U手上有一个整数数组,他想知道如果从数组中删除任意一个元素后,能得到的长度为 k 的子数组和的最大值。你能帮小U计算出这个结果吗? 如果数组恰好为 k 个元素,那么不进行删除操作。 from collections import deque

def solution(n, k, nums): if k > n: return None

# 计算第一个窗口的和
current_sum = sum(nums[:k])
### 思路:
  1. 输入参数:接收三个参数:n(数组长度),k(子数组长度),nums(整数数组)。

  2. 边界条件检查:如果 k 大于 n,返回 None,表示无法找到长度为 k 的子数组。

  3. 初始化

    • 计算第一个长度为 k 的子数组的和,存储在 current_sum 中,并初始化结果 res 为该和。
    • 使用一个双端队列 min_deque 来维护当前窗口的最小值索引。
  4. 维护最小值

    • 在初始窗口中填充 min_deque,确保队列中的索引对应的值是单调递增的。
  5. 滑动窗口遍历

    • 从索引 k 开始,向右遍历数组。

    • 在每一步中:

      • 更新结果 res 为当前窗口的和加上新的元素,减去当前窗口的最小值。
      • 移动窗口,更新 current_sum,通过添加新元素和去掉旧元素来调整和。
      • 更新 min_deque,确保它只包含当前窗口的有效索引,并且保持单调递增。
  6. 返回结果:最终返回 res,即所有可能的长度为 k 的子数组的最大和。

通过这些步骤,该算法有效地找到具有最大和的长度为 k 的子数组,并同时考虑了加上新元素和减去窗口内最小值的情况。

res = current_sum

# 创建一个双端队列来维护当前窗口的最小值索引
min_deque = deque()
for i in range(k):
    while min_deque and nums[min_deque[-1]] >= nums[i]:
        min_deque.pop()
    min_deque.append(i)

for i in range(k, n):
    # 更新结果
    res = max(res, current_sum + nums[i] - nums[min_deque[0]])
    
    # 移动窗口
    current_sum += nums[i] - nums[i - k]
    
    # 更新最小值
    while min_deque and min_deque[0] <= i - k:
        min_deque.popleft()
    
    while min_deque and nums[min_deque[-1]] >= nums[i]:
        min_deque.pop()
    min_deque.append(i)

return res
### 思路:
  1. 输入参数:接收三个参数:n(数组长度),k(子数组长度),nums(整数数组)。

  2. 边界条件检查:如果 k 大于 n,返回 None,表示无法找到长度为 k 的子数组。

  3. 初始化

    • 计算第一个长度为 k 的子数组的和,存储在 current_sum 中,并初始化结果 res 为该和。
    • 使用一个双端队列 min_deque 来维护当前窗口的最小值索引。
  4. 维护最小值

    • 在初始窗口中填充 min_deque,确保队列中的索引对应的值是单调递增的。
  5. 滑动窗口遍历

    • 从索引 k 开始,向右遍历数组。

    • 在每一步中:

      • 更新结果 res 为当前窗口的和加上新的元素,减去当前窗口的最小值。
      • 移动窗口,更新 current_sum,通过添加新元素和去掉旧元素来调整和。
      • 更新 min_deque,确保它只包含当前窗口的有效索引,并且保持单调递增。
  6. 返回结果:最终返回 res,即所有可能的长度为 k 的子数组的最大和。

通过这些步骤,该算法有效地找到具有最大和的长度为 k 的子数组,并同时考虑了加上新元素和减去窗口内最小值的情况。