当前位置: 代码迷 >> 综合 >> 1191 K 次串联后最大子数组之和(分析)
  详细解决方案

1191 K 次串联后最大子数组之和(分析)

热度:52   发布时间:2024-02-05 23:13:03.0

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# 否则返回可能加上的多周期和