字节跳动青训营刷题笔记3| 豆包MarsCode AI刷题

88 阅读3分钟

难度:中等

关键词:滑动窗口

问题描述

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


测试样例

样例1:

输入:n = 5,k = 3,nums = [2, 1, 3, -1, 4]
输出:8

样例2:

输入:n = 6,k = 2,nums = [-1, -1, 5, -2, 3, 4]
输出:8

样例3:

输入:n = 4,k = 2,nums = [-5, -3, 2, 1]
输出:3

代码思路分解

  1. 基础处理

    • 如果数组的长度 n 等于 k,说明不可能删除元素,所以直接返回整个数组的和。
  2. 滑动窗口方法

    • 目的:高效计算长度为 k 的子数组的最大和,而不需要每次重新遍历和求和。

    • 方法

      1. 首先计算数组中前 k 个元素的总和 current_sum,并将其作为初始的 max_sum_k
      2. 使用滑动窗口:对于每个新元素 nums[i],将它加入 current_sum,并减去滑出窗口的旧元素 nums[i - k]。这样就可以在 O(1) 时间内更新 current_sum
      3. 更新 max_sum_k,保持滑动窗口中长度为 k 的子数组的最大和。
  3. 删除每个元素,重新计算最大和

    • 思路:模拟删除数组中的每个元素,并重新计算删除后的数组中长度为 k 的子数组的最大和。

    • 方法

      1. 使用切片操作 temp_nums = nums[:i] + nums[i + 1:] 创建一个新数组,表示删除了索引为 i 的元素。
      2. 在这个新数组上使用滑动窗口方法,计算长度为 k 的子数组的最大和。
      3. 在所有删除情况下,记录最大和 max_sum_with_removal
  4. 返回结果

    • 返回所有情况下长度为 k 的子数组和的最大值 max_sum_with_removal
def solution(n, k, nums):
    # 如果数组长度正好为 k,不进行删除操作,直接返回总和
    if n == k:
        return sum(nums)
    
    # Step 1: 使用滑动窗口计算长度为 k 的子数组的初始最大和
    max_sum_k = sum(nums[:k])  # 计算前 k 个元素的总和
    current_sum = max_sum_k  # 当前子数组和

    # 使用滑动窗口找到任意长度为 k 的子数组的最大和
    for i in range(k, n):  # 从索引 k 开始遍历到数组的末尾
        current_sum += nums[i] - nums[i - k]  # 更新当前子数组和
        max_sum_k = max(max_sum_k, current_sum)  # 更新最大和

    # Step 2: 尝试删除每个元素,计算删除后的长度为 k 的子数组的最大和
    max_sum_with_removal = max_sum_k  # 初始化删除后子数组和的最大值
    for i in range(n):  # 遍历每个元素,模拟删除
        temp_nums = nums[:i] + nums[i + 1:]  # 删除索引为 i 的元素
        current_sum = sum(temp_nums[:k])  # 计算删除后数组前 k 个元素的和
        max_sum = current_sum  # 当前最大和

        # 对删除后的数组使用滑动窗口
        for j in range(k, n - 1):  # 滑动窗口从 k 移动到数组末尾
            current_sum += temp_nums[j] - temp_nums[j - k]  # 更新当前子数组和
            max_sum = max(max_sum, current_sum)  # 更新最大和

        max_sum_with_removal = max(max_sum_with_removal, max_sum)  # 更新全局最大和
    
    return max_sum_with_removal

时间复杂度分析

  • 滑动窗口的时间复杂度是 O(n)O(n)
  • 尝试删除每个元素并重新计算的时间复杂度是 O(n2)O(n^2),因为需要对每个元素都执行一个滑动窗口操作。