LeetCode 题解工作台

K 次串联后最大子数组之和

给定一个整数数组 arr 和一个整数 k ,通过重复 k 次来修改数组。 例如,如果 arr = [1, 2] , k = 3 ,那么修改后的数组将是 [1, 2, 1, 2, 1, 2] 。 返回修改后的数组中的最大的子数组之和。注意,子数组长度可以是 0 ,在这种情况下它的总和也是 0 。 由于…

category

2

题型

code_blocks

4

代码语言

hub

3

相关题

当前训练重点

中等 · 状态·转移·动态规划

bolt

答案摘要

我们记数组 所有元素之和为 ,最大前缀和为 ,最小前缀和为 ,最大子数组和为 。 遍历数组 ,对于每个元素 ,我们更新 $s = s + x$, $mxPre = \max(mxPre, s)$, $miPre = \min(miPre, s)$, $mxSub = \max(mxSub, s - miPre)$。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给定一个整数数组 arr 和一个整数 k ,通过重复 k 次来修改数组。

例如,如果 arr = [1, 2] , k = 3 ,那么修改后的数组将是 [1, 2, 1, 2, 1, 2]

返回修改后的数组中的最大的子数组之和。注意,子数组长度可以是 0,在这种情况下它的总和也是 0

由于 结果可能会很大,需要返回结果对 109 + 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 <= 105
  • 1 <= k <= 105
  • -104 <= arr[i] <= 104
lightbulb

解题思路

方法一:前缀和 + 分类讨论

我们记数组 arrarr 所有元素之和为 ss,最大前缀和为 mxPremxPre,最小前缀和为 miPremiPre,最大子数组和为 mxSubmxSub

遍历数组 arrarr,对于每个元素 xx,我们更新 s=s+xs = s + x, mxPre=max(mxPre,s)mxPre = \max(mxPre, s), miPre=min(miPre,s)miPre = \min(miPre, s), mxSub=max(mxSub,smiPre)mxSub = \max(mxSub, s - miPre)

接下来,我们考虑 kk 的取值情况:

  • k=1k = 1 时,答案为 mxSubmxSub
  • k2k \ge 2 时,如果最大子数组横跨两个 arrarr,那么答案为 mxPre+mxSufmxPre + mxSuf,其中 mxSuf=smiPremxSuf = s - miPre
  • k2k \ge 2s>0s > 0 时,如果最大子数组横跨三个 arrarr,那么答案为 (k2)×s+mxPre+mxSuf(k - 2) \times s + mxPre + mxSuf

最后,我们返回答案对 109+710^9 + 7 取模的结果。

时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。其中 nn 为数组 arrarr 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution:
    def kConcatenationMaxSum(self, arr: List[int], k: int) -> int:
        s = mx_pre = mi_pre = mx_sub = 0
        for x in arr:
            s += x
            mx_pre = max(mx_pre, s)
            mi_pre = min(mi_pre, s)
            mx_sub = max(mx_sub, s - mi_pre)
        ans = mx_sub
        mod = 10**9 + 7
        if k == 1:
            return ans % mod
        mx_suf = s - mi_pre
        ans = max(ans, mx_pre + mx_suf)
        if s > 0:
            ans = max(ans, (k - 2) * s + mx_pre + mx_suf)
        return ans % mod
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Can the candidate handle the k=1 base case effectively?

  • question_mark

    Does the candidate recognize the importance of prefix and suffix sums for larger k?

  • question_mark

    How efficiently does the candidate scale the solution for large k values?

warning

常见陷阱

外企场景
  • error

    Forgetting to handle the case where the sub-array sum is zero.

  • error

    Not properly combining the prefix and suffix sums when k > 1.

  • error

    Inefficient solutions that do not scale for large values of k.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    What happens if we reduce k to 1? How does the solution change?

  • arrow_right_alt

    Can this approach be used for negative numbers in the array?

  • arrow_right_alt

    How would you handle cases where all elements in the array are negative?

help

常见问题

外企场景

K 次串联后最大子数组之和题解:状态·转移·动态规划 | LeetCode #1191 中等