AI刷题-T92 子数组和的最大值问题- 题解

32 阅读2分钟

题目链接:子数组和的最大值问题 - MarsCode

问题理解

我们需要在一个整数数组中找到一个长度为 k 的子数组,使得其和最大。如果数组长度恰好为 k,则不进行删除操作。否则,我们可以删除数组中的任意一个元素,然后再找到长度为 k 的子数组,使得其和最大。

数据结构选择

我们可以使用滑动窗口(Sliding Window)来计算子数组的和,这样可以避免重复计算,提高效率。

算法步骤

  1. 特殊情况处理:如果数组长度 n 恰好等于 k,直接计算整个数组的和并返回。

  2. 滑动窗口计算

    • 计算原始数组中所有长度为 k 的子数组的和,并记录最大值。
    • 对于每个可能删除的元素,重新计算删除该元素后的数组中所有长度为 k 的子数组的和,并记录最大值。
  3. 比较和返回:比较所有情况下的最大和,返回最大值。

优化思路

  • 可以预先计算前缀和(Prefix Sum),这样在计算子数组和时可以更快。
  • 在删除元素后,利用前缀和快速计算新的子数组和。

代码

public class Main {
    public static int solution(int n, int k, int[] nums) {
        if (n == k) {
            int sum = 0;
            for (int num : nums) {
                sum += num;
            }
            return sum;
        }
        
        int maxSum = Integer.MIN_VALUE;
        
        // 计算原始数组的前缀和
        int[] prefixSum = new int[n + 1];
        for (int i = 0; i < n; i++) {
            prefixSum[i + 1] = prefixSum[i] + nums[i];
        }
        
        for (int i = 0; i < n; i++) {
            // 删除第 i 个元素后的子数组和
            int sum = 0;
            // 使用滑动窗口计算子数组和
            for (int start = 0; start <= n - 1 - k; start++) {
                if (start <= i && i < start + k) {
                    // 如果删除的元素在当前窗口内,跳过这个窗口
                    continue;
                }
                // 计算子数组和
                sum = prefixSum[start + k] - prefixSum[start];
                maxSum = Math.max(maxSum, sum);
            }
        }
        
        return maxSum;
    }

    public static void main(String[] args) {
        // Add your test cases here
        System.out.println(solution(5, 3, new int[]{2, 1, 3, -1, 4}) == 8);
    }
}