📜  门| GATE 2017 MOCK II |第54章(1)

📅  最后修改于: 2023-12-03 15:28:36.441000             🧑  作者: Mango

门| GATE 2017 MOCK II |第54章

这是一道GATE 2017 MOCK II的题目,属于数据结构与算法模块中的第54章。

题目描述

给定一个由n个整数组成的数组a(0 <= n <= 10^4),请编写一个程序,找出其中的所有子阵列和的最大值。

子阵列定义为数组a中连续的元素列表。例如,如果数组a是{1,2,3,4,5},那么它的所有子阵列有:{1},{2},{3},{4},{5},{1,2},{2,3},{3,4},{4,5},{1,2,3},{2,3,4},{3,4,5},{1,2,3,4},{2,3,4,5},{1,2,3,4,5}。

子阵列和定义为子阵列中所有元素的总和。例如,阵列{1,2,3,4,5} 的子阵列和有:{1} = 1,{1,2} = 3,{1,2,3} = 6,{1,2,3,4} = 10,{1,2,3,4,5} = 15。

输入格式

第一行包含一个整数t,表示测试用例的数量。

每个测试用例包含两个整数n和k,分别表示数组a的大小和每个子阵列中最多包含元素的数量。

接下来的一行包含n个整数a1、a2……an,表示数组a中的元素。

输出格式

对于每个测试用例,输出一个整数,表示数组a中子阵列和的最大值。

示例

输入样例:

2
5 3
2 3 4 1 5
5 2
2 5 4 1 3

输出样例:

12
14
解题思路

前缀和+双指针

代码
def max_subarray_sum(n, k, a):
    prefix_sum = [0]
    for i in range(n):
        prefix_sum.append(prefix_sum[-1] + a[i])
    left, right = 0, k
    ans = max(prefix_sum[k] - prefix_sum[0], 0)
    while right <= n:
        ans = max(ans, prefix_sum[right] - prefix_sum[left])
        left += 1
        right += 1
    return ans


if __name__ == "__main__":
    t = int(input())
    for _ in range(t):
        n, k = map(int, input().split())
        a = list(map(int, input().split()))
        print(max_subarray_sum(n, k, a))

解释:

首先将这个数组的前缀和求出来,这样可以用O(1)的时间复杂度计算子阵列的和,然后使用双指针维护所有长度为k的区间。由于这个数组的元素可以为负数,所以如果某个子阵列的和小于零,就没有必要将它和当前答案比较了。