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

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 List


class Solution:
    def kConcatenationMaxSum(self, arr: List[int], k: int) -> int:
        # 这道题目很有意思
        n = len(arr)
        s, d = [0] * (n + 1), [0] * n
        for 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 List


class Solution:
    # 下面这个也是从领扣上拷贝下来的代码
    def kConcatenationMaxSum(self, arr: List[int], k: int) -> int:
        s, maxs = 0, 0
        for 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
        # 否则返回可能加上的多周期和

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/107770481