📅  最后修改于: 2023-12-03 15:28:36.441000             🧑  作者: Mango
这是一道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的区间。由于这个数组的元素可以为负数,所以如果某个子阵列的和小于零,就没有必要将它和当前答案比较了。