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

80 阅读1分钟

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

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

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

由于 结果可能会很大,需要返回的 109 + 7 的  。

算法:
方法一:动态规划

将k数组拆成为 2次和k-2次的两部分 对于2次的部分,有两种情况 image.png

  1. 在一个arr内取得最大子数组和。剩下的k-1个重复数组是多余的。
  2. 在两个arr内取到最大子数组和。并且在剩下k -2个重复数组中重复k - 2次,得到为(k-2)*sum的数组和
func kConcatenationMaxSum(arr []int, k int) int {
    maxOfEnd, maxOfSofar := 0, 0
    sum := 0 
    n := len(arr)
    for i := range arr {
        sum = sum + arr[i]
    }
    
    count := min(k, 2) * n
    for i := 0; i < count; i ++ {
        val := arr[i % n]
        maxOfEnd = max(maxOfEnd + val, val)
        maxOfSofar = max(maxOfSofar, maxOfEnd)
    }
    if sum > 0 {
        for k > 2 {
            maxOfSofar = (maxOfSofar + sum) % 1000000007
            k --
        }
    }
    // 没有执行k > 2得循环,而maxOfSofar已经是一个很大的数
    return maxOfSofar % 1000000007
}

func min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}