[Swift]LeetCode1031. 两个非重叠子数组的最大和 | Maximum Sum of Two Non-Overlapping Subarrays...

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10744670.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

Given an array A of non-negative integers, return the maximum sum of elements in two non-overlapping (contiguous) subarrays, which have lengths L and M.  (For clarification, the L-length subarray could occur before or after the M-length subarray.)

Formally, return the largest V for which V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + ... + A[j+M-1]) and either:

  • 0 <= i < i + L - 1 < j < j + M - 1 < A.length, or
  • 0 <= j < j + M - 1 < i < i + L - 1 < A.length.

Example 1:

Input: A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2
Output: 20
Explanation: One choice of subarrays is [9] with length 1, and [6,5] with length 2.

Example 2:

Input: A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2
Output: 29
Explanation: One choice of subarrays is [3,8,1] with length 3, and [8,9] with length 2.

Example 3:

Input: A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3
Output: 31
Explanation: One choice of subarrays is [5,6,0,9] with length 4, and [3,8] with length 3.

Note:

  1. L >= 1
  2. M >= 1
  3. L + M <= A.length <= 1000
  4. 0 <= A[i] <= 1000

给出非负整数数组 A ,返回两个非重叠(连续)子数组中元素的最大和,子数组的长度分别为 L 和 M。(这里需要澄清的是,长为 L 的子数组可以出现在长为 M 的子数组之前或之后。)

从形式上看,返回最大的 V,而 V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + ... + A[j+M-1]) 并满足下列条件之一:

  • 0 <= i < i + L - 1 < j < j + M - 1 < A.length, 或
  • 0 <= j < j + M - 1 < i < i + L - 1 < A.length.

示例 1:

输入:A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2
输出:20
解释:子数组的一种选择中,[9] 长度为 1,[6,5] 长度为 2。

示例 2:

输入:A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2
输出:29
解释:子数组的一种选择中,[3,8,1] 长度为 3,[8,9] 长度为 2。

示例 3:

输入:A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3
输出:31
解释:子数组的一种选择中,[5,6,0,9] 长度为 4,[0,3,8] 长度为 3。

提示:

  1. L >= 1
  2. M >= 1
  3. L + M <= A.length <= 1000
  4. 0 <= A[i] <= 1000

Runtime: 24 ms
Memory Usage: 19.1 MB
 1 class Solution {
 2     let N:Int = 1010
 3     var prefix:[Int] = [Int](repeating:0,count:1010)
 4     func maxSumTwoNoOverlap(_ A: [Int], _ L: Int, _ M: Int) -> Int {
 5         var n:Int = A.count
 6         for i in 1...n
 7         {
 8             prefix[i] = prefix[i - 1] + A[i - 1]
 9         }
10         var ans:Int = 0
11         var best_l:Int = 0
12         for i in (L + M)...n
13         {
14             best_l = max(best_l, prefix[i - M] - prefix[i - M - L])
15             ans = max(ans, best_l + prefix[i] - prefix[i - M])
16         }
17         var best_m:Int = 0
18         for i in (L + M)...n
19         {
20             best_m = max(best_m, prefix[i - L] - prefix[i - M - L])
21             ans = max(ans, best_m + prefix[i] - prefix[i - L])
22         }
23         return ans        
24     }
25 }

24ms 
 1 class Solution {
 2     func maxSumTwoNoOverlap(_ A: [Int], _ L: Int, _ M: Int) -> Int {
 3         var leftMax = [Int](repeating: 0, count: A.count)
 4         var curMax = 0, curSum = 0
 5         for i in A.indices {
 6             curSum += i < M ?  A[i] : A[i] - A[i-M]
 7             curMax = max(curMax, curSum)
 8             leftMax[i] = curMax
 9         }
10 
11         var rightMax = [Int](repeating: 0, count: A.count+1)
12         var i = A.count - 1, ans = 0
13         curMax = 0; curSum = 0
14         while i >= 0 {
15             curSum += (i + M > A.count - 1) ? A[i] : A[i] - A[i+M]
16             curMax = max(curMax, curSum)
17             rightMax[i] = curMax
18             i -= 1
19         }
20 
21         curSum = 0
22         for i in A.indices {
23             curSum += i < L ?  A[i] : A[i] - A[i-L]
24             let leftMax =  i >= L ? leftMax[i-L] : 0
25             ans = max(ans, max(leftMax, rightMax[i+1]) + curSum)
26         }
27         return ans
28     }
29 }

84ms

 1 class Solution {
 2     func maxSumTwoNoOverlap(_ A: [Int], _ L: Int, _ M: Int) -> Int {
 3         var sumLs = [Int](repeating: 0, count: A.count)
 4         var sumMs = [Int](repeating: 0, count: A.count)
 5         var forwardMaxLs = [Int](repeating: 0, count: A.count)
 6         var backwardMaxLs = [Int](repeating: 0, count: A.count)
 7         var forwardMaxMs = [Int](repeating: 0, count: A.count)
 8         var backwardMaxMs = [Int](repeating: 0, count: A.count)
 9 
10         var sumL = 0
11         var sumM = 0
12         for i in 0..<A.count {
13             sumL += A[i]
14             if i >= L - 1 {
15                 if i >= L {
16                     sumL -= A[i - L]
17                 }
18                 sumLs[i] = sumL
19             }
20             sumM += A[i]
21             if i >= M - 1 {
22                 if i >= M {
23                     sumM -= A[i - M]
24                 }
25                 sumMs[i] = sumM
26             }
27         }
28         var maxSumL = Int.min
29         var maxSumM = Int.min
30         for i in 0..<A.count {
31             maxSumL = max(maxSumL, sumLs[i])
32             forwardMaxLs[i] = maxSumL
33             maxSumM = max(maxSumM, sumMs[i])
34             forwardMaxMs[i] = maxSumM
35         }
36         maxSumL = Int.min
37         maxSumM = Int.min
38         for i in (0..<A.count).reversed() {
39             maxSumL = max(maxSumL, sumLs[i])
40             backwardMaxLs[i] = maxSumL
41             maxSumM = max(maxSumM, sumMs[i])
42             backwardMaxMs[i] = maxSumM
43         }
44         var maxSum = Int.min
45         for l in 0..<A.count {
46             var m = A.count - 1
47             while l <= m - M {
48                 maxSum = max(maxSum, forwardMaxLs[l] + backwardMaxMs[m])
49                 m -= 1
50             }
51         }
52         for m in 0..<A.count {
53             var l = A.count - 1
54             while m <= l - L {
55                 maxSum = max(maxSum, backwardMaxLs[l] + forwardMaxMs[m])
56                 l -= 1
57             }
58         }
59         return maxSum
60     }
61 }

108ms

 1 class Solution {
 2     func maxSumTwoNoOverlap(_ A: [Int], _ L: Int, _ M: Int) -> Int {
 3         var prefixSums: [Int] = [0]
 4         var sum = 0
 5         for num in A {
 6             sum += num
 7             prefixSums.append(sum)
 8         }
 9         var res = 0
10         for lRight in L..<prefixSums.count {
11             let lSum = prefixSums[lRight] - prefixSums[lRight - L]
12             for mRight in stride(from: lRight + M, to: prefixSums.count, by: 1) {
13                 let mSum = prefixSums[mRight] - prefixSums[mRight - M]
14                 let total = mSum + lSum
15                 res = max(res, total)
16             }
17             
18             for mRight in stride(from: M, to: lRight - L, by: 1) {
19                 let mSum = prefixSums[mRight] - prefixSums[mRight - M]
20                 let total = mSum + lSum
21                 res = max(res, total)
22             }
23         }
24         return res
25     }
26 }

 

转载于:https://www.cnblogs.com/strengthen/p/10744670.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值