Maximum Sum Circular Subarray
Description
Given a circular array C of integers represented by A
, find the maximum possible sum of a non-empty subarray of C.
Here, a circular array means the end of the array connects to the beginning of the array. (Formally, C[i] = A[i]
when 0 <= i < A.length
, and C[i+A.length] = C[i]
when i >= 0
.)
Also, a subarray may only include each element of the fixed buffer A
at most once. (Formally, for a subarray C[i], C[i+1], ..., C[j]
, there does not exist i <= k1, k2 <= j
with k1 % A.length = k2 % A.length
.)
Example 1:
Input: [1,-2,3,-2] Output: 3 Explanation: Subarray [3] has maximum sum 3
Example 2:
Input: [5,-3,5] Output: 10 Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10
Example 3:
Input: [3,-1,2,-1] Output: 4 Explanation: Subarray [2,-1,3] has maximum sum 2 + (-1) + 3 = 4
Example 4:
Input: [3,-2,2,-3] Output: 3 Explanation: Subarray [3] and [3,-2,2] both have maximum sum 3
Example 5:
Input: [-2,-3,-1] Output: -1 Explanation: Subarray [-1] has maximum sum -1
Note:
-30000 <= A[i] <= 30000
1 <= A.length <= 30000
Solution(javascript)
/** 对着着53题 单调队列 O(n)
*
* @param {number[]} A
* @return {number}
*/
// const maxSubarraySumCircular = function (A = []) {
// let max = A[0]
// const deque = [0]
// let start = 0
// const sum = [A[0]]
// for (let i = 1; i < 2 * A.length; i++) {
// sum[i] = sum[i - 1] + A[i % A.length]
// }
// for (let i = 1; i < 2 * A.length; i++) {
// while (i - deque[start] > A.length) {
// start += 1
// }
// max = Math.max(sum[i] - sum[deque[start]], max)
// while (sum[i] < sum[deque[deque.length - 1]]) {
// deque.pop()
// }
// deque.push(i)
// }
// return max
// }
// https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/One-Pass
// 类似 53 题
const maxSubarraySumCircular = function (A = []) {
let max = A[0]
let min = A[0]
let currentMax = max
let currentMin = min
let sum = A[0]
for (let i = 1; i < A.length; i++) {
currentMax = A[i] + Math.max(currentMax, 0)
max = Math.max(max, currentMax)
currentMin = A[i] + Math.min(currentMin, 0)
min = Math.min(min, currentMin)
sum += A[i]
}
return max < 0 ? max : Math.max(max, sum - min)
}