1. 问题描述:
给你一个整数数组 arr 和一个整数 k。首先,我们要对该数组进行修改,即把原数组 arr 重复 k 次。举个例子,如果 arr = [1, 2] 且 k = 3,那么修改后的数组就是 [1, 2, 1, 2, 1, 2]。然后,请你返回修改后的数组中的最大的子数组之和。注意,子数组长度可以是 0,在这种情况下它的总和也是 0。由于 结果可能会很大,所以需要 模(mod) 10^9 + 7 后再返回。
示例 1:
输入:arr = [1,2], k = 3
输出:9
示例 2:
输入:arr = [1,-2,1], k = 5
输出:2
示例 3:输入:arr = [-1,-2], k = 7
输出:0
提示:
1 <= arr.length <= 10^5
1 <= k <= 10^5
-10^4 <= arr[i] <= 10^4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-concatenation-maximum-sum
2. 思路分析:
① 一开始的时候没有什么思路,所以看了一下题解,发现一个很不错的思路,第一种解决方法是需要通过循环计算数组元素的前缀和,然后计算中间k - 2个周期的最大连续子数组的和,可以计算出所有元素的元素和并且与0比较看一下哪一个最大那么就是k - 2个周期的最大连续和(有可能树负数所以为k - 2个周期的最大连续子数组的和是0),之前计算前缀和的时候可以使用列表来记录到达当前位置的前缀和,这样就可以计算出一个周期的最大前缀和与最大后缀和,将其拼接在k - 2个周期的后面与前面即可计算出k个周期的最大连续子数组的和
② 第二种方法是在循环中计算出两个周期的最大连续子数组的和,然后计算出k - 2个周期的最大子序和,将2个周期的最大子序和与k - 2的最大子序个加起来的结果就是答案(两个周期可以拼接在最前面或者是最后面),题解:https://leetcode-cn.com/problems/k-concatenation-maximum-sum/solution/1191-k-ci-chuan-lian-hou-zui-da-zi-shu-zu-zhi-he-l/
3. 代码如下:
from typing import Listclass Solution:def kConcatenationMaxSum(self, arr: List[int], k: int) -> int:# 这道题目很有意思n = len(arr)s, d = [0] * (n + 1), [0] * nfor i in range(n):s[i + 1] = s[i] + arr[i] # 前缀和d[i] = max(d[i - 1] + arr[i], 0) # 最大连续和if k == 1:return max(d) # 如果只有一个周期,就直接输出最大的连续和return max(max(d), max(s[n], 0) * (k - 2) + s[n] - min(s) + max(s)) % 1000000007 # 比较一个周期的最大连续和以及多个周期的总和大小
from typing import Listclass Solution:# 下面这个也是从领扣上拷贝下来的代码def kConcatenationMaxSum(self, arr: List[int], k: int) -> int:s, maxs = 0, 0for a in arr * min(2, k):s = a if s < 0 else s + a # 连续和if s > maxs:maxs = s # 最大连续和print(maxs)if k <= 2:return maxs # 两个周期以内之间返回最大连续和return (max(sum(arr), 0) * (k - 2) + maxs) % 1000000007# 否则返回可能加上的多周期和