伴学笔记:求解删除一个元素后的最大子数组和 | 豆包MarsCode AI刷题

64 阅读4分钟

伴学笔记:如何求解删除一个元素后的最大子数组和?

问题描述:
小U手中有一个整数数组,他想知道在删除任意一个元素后,能得到的长度为 k 的子数组和的最大值。若数组正好是 k 个元素,且不能删除任何元素。我们需要编写程序来求解这个问题。


思路分析 🧠

1. 问题分析:

  • 如果数组长度 n 和子数组长度 k 相等,那就直接返回数组的和,因为不能删除任何元素。

  • 否则,我们需要:

    1. 计算数组的所有长度为 k 的子数组的和。
    2. 考虑删除每个元素后,如何调整子数组的和。

    关键的技巧是 滑动窗口 技术,用于高效计算长度为 k 的子数组和。

2. 滑动窗口:

滑动窗口的核心思想是:计算一个子数组的和后,向右滑动窗口时,只需要将左边的元素移除,右边的元素加入。通过这种方式,我们可以避免每次都重新计算子数组和,从而提高效率。

3. 步骤:

  • 步骤1:n == k,直接返回数组的和。
  • 步骤2:n > k,遍历数组中的每个元素,尝试删除它,然后通过滑动窗口计算删除后的子数组和的最大值。

代码讲解 📜

def solution(n, k, nums):
    # 如果数组长度等于k,不需要删除元素
    if n == k:
        return sum(nums)

    # 滑动窗口求和的辅助函数
    def max_k_subarray_sum(arr, k):
        # 初始化滑动窗口
        current_sum = sum(arr[:k])  
        max_sum = current_sum
        # 使用滑动窗口方法更新窗口和
        for i in range(k, len(arr)):
            current_sum += arr[i] - arr[i - k]  # 更新窗口和
            max_sum = max(max_sum, current_sum)  # 更新最大和
        return max_sum

    max_result = float('-inf')  # 用于记录最终的最大值

    # 遍历删除每个元素
    for i in range(n):
        # 删除第 i 个元素,得到新数组
        new_nums = nums[:i] + nums[i+1:]
        # 计算删除后的最大子数组和
        max_sum = max_k_subarray_sum(new_nums, k)
        # 更新最大和
        max_result = max(max_result, max_sum)

    return max_result  # 返回最终的结果


if __name__ == "__main__":
    # 测试用例
    print(solution(5, 3, [2, 1, 3, -1, 4]))  # 输出:8

代码细节解析 🔍

  1. max_k_subarray_sum 函数:

    • 这个函数用于计算长度为 k 的子数组的最大和。
    • 初始时,计算前 k 个元素的和 current_sum
    • 然后通过滑动窗口,逐个移动窗口右端,每次更新窗口和 current_sum,并更新最大和 max_sum
  2. 删除元素后的处理:

    • 使用一个 for 循环,遍历数组中的每个元素。
    • 对每个元素,删除它并创建一个新的数组 new_nums,然后计算 new_nums 中长度为 k 的子数组的最大和。
  3. 全局最大值更新:

    • 每次计算删除后的子数组和后,更新 max_result 变量,最终返回最优解。

测试样例分析 🔧

样例 1:

输入:

n = 5
k = 3
nums = [2, 1, 3, -1, 4]

执行步骤:

  1. 不删除元素时,长度为 k 的子数组最大和为 2 + 1 + 3 = 6

  2. 删除任意一个元素,重新计算最大子数组和。

    • 删除 2 后,子数组为 [1, 3, -1],和为 3
    • 删除 1 后,子数组为 [2, 3, -1],和为 4
    • 删除 3 后,子数组为 [2, 1, -1],和为 2
    • 删除 -1 后,子数组为 [2, 1, 4],和为 7
  3. 返回最终结果 8(删除 -1 后,最大和为 8)。

样例 2:

输入:

n = 6
k = 2
nums = [-1, -1, 5, -2, 3, 4]

执行步骤:

  1. 不删除元素时,长度为 k 的子数组最大和为 5 + (-2) = 3
  2. 删除任意一个元素,重新计算最大子数组和。
  3. 返回最终结果 8(删除 -1 后,最大和为 8)。

样例 3:

输入:

n = 4
k = 2
nums = [-5, -3, 2, 1]

执行步骤:

  1. 不删除元素时,长度为 k 的子数组最大和为 -3 + 2 = -1
  2. 删除任意一个元素,重新计算最大子数组和。
  3. 返回最终结果 3(删除 -5 后,最大和为 3)。

总结 🌟

通过使用 滑动窗口遍历删除元素 的方法,我们可以高效地计算删除一个元素后,得到的最大子数组和。此方法的时间复杂度为 O(n*k),其中 n 为数组长度,k 为子数组长度。

希望这篇笔记帮助你理解了如何解决这个问题!🌸