1. 问题描述:
给定一个长度为 n 的数组 d1,d2,…,dn。现在,要将该数组从中间截断,得到三个子数组(可以为空)。不妨设第一个子数组包含 a 个元素,第二个子数组包含 b 个元素,第三个子数组包含 c 个元素。那么三个子数组的各元素之和 sum1,sum2,sum3 依次为:
注意,空数组的各元素之和为 0。我们希望截断后的三个子数组满足:sum1 = sum3。满足上一条件的情况下,sum1 尽可能大。请你计算并输出 sum1 的最大可能值。显然,本题一定有解,因为可以令 a = 0,b = n,c = 0。
输入格式
第一行包含整数 n。第二行包含 n 个整数 d1,d2,…,dn。
输出格式
输出一个整数,表示 sum1 的最大可能值。
数据范围
前 6 个测试点满足 1 ≤ n ≤ 10。
所有测试点满足 1 ≤ n ≤ 2 × 10 ^ 5,1 ≤ di ≤ 10 ^ 9。
输入样例1:
5
1 3 1 1 4
输出样例1:
5
输入样例2:
5
1 3 2 1 4
输出样例2:
4
输入样例3:
3
4 1 2
输出样例3:
0
来源:https://www.acwing.com/problem/content/4300/
2. 思路分析:
分析题目可以知道我们只需要让数组最前面的一段与最后面的一段相等即可,由于所有数字都是大于等于1的所以前缀和是不断增大的,所以我们只需要维护前缀和与后缀和即可,使用双指针找到最后一次相等的位置那么数组最前面与最后面的和一定是最大的。
3. 代码如下:
class Solution:
def process(self):
n = int(input())
q = list(map(int, input().split()))
# s1, s2分别为前缀和与后缀和, 下标从1开始比较好处理
s1, s2 = [0] * (n + 10), [0] * (n + 10)
for i in range(1, n + 1):
s1[i] += s1[i - 1] + q[i - 1]
for i in range(n, 0, -1):
s2[i] += s2[i + 1] + q[i - 1]
# 双指针从前往后与从后往前遍历
i, j = 1, n
res = 0
while i < j:
# 说明i需要往后移动这样两者的和才越靠近
if s1[i] < s2[j]:
i += 1
# j需要往前移动
elif s1[i] > s2[j]:
j -= 1
else:
# 说明当前找到了相等的区间, 更新答案即可
res = s1[i]
i += 1
j -= 1
return res
if __name__ == '__main__':
print(Solution().process())