AlgoMaster Logo

Maximum Sum Circular Subarray

Last Updated: March 22, 2026

medium
3 min read

Understanding the Problem

At first glance, this looks like the classic Maximum Subarray problem (Kadane's algorithm), but with a twist: the array is circular. That means a valid subarray can wrap around from the end of the array back to the beginning. For example, in [5, -3, 5], the subarray [5, 5] wraps around, taking the last element and the first element, for a sum of 10.

So we need to consider two types of subarrays:

  1. Normal subarrays that sit somewhere in the middle of the array (no wrapping).
  2. Wrapping subarrays that include some suffix of the array and some prefix of the array.

The key question is: how do we efficiently handle the wrapping case without literally doubling the array and checking every possibility?

Key Constraints:

  • 1 <= n <= 3 * 10^4 means our solution needs to be O(n) or O(n log n). An O(n^2) approach would handle 3 10^4 elements (about 9 10^8 operations), which is borderline and likely too slow.
  • -3 * 10^4 <= nums[i] <= 3 * 10^4 means values can be negative, positive, or zero. We need to handle the all-negatives case carefully.

Approach 1: Brute Force

Intuition

The most straightforward idea: just try every possible subarray, including the ones that wrap around, and track the maximum sum.

For each starting index i, we extend the subarray element by element (using modular arithmetic to wrap around), keeping a running sum and updating our answer. We stop after including at most n elements, since each element can appear at most once.

Algorithm

  1. Initialize maxSum to negative infinity.
  2. For each starting index i from 0 to n-1:
    • Initialize currentSum = 0.
    • For each length j from 0 to n-1:
      • Add nums[(i + j) % n] to currentSum.
      • Update maxSum = max(maxSum, currentSum).
  3. Return maxSum.

Example Walkthrough

1Start: i=0, try all subarrays starting at index 0
0
i=0
5
1
-3
2
5
1/5

Code

For every starting index, we recompute the sum from scratch by extending one element at a time. That is n full scans of the array. Can we break the circular problem into pieces that standard Kadane's can solve in a single pass?

Approach 2: Kadane's with Min Subarray (Optimal)

Intuition

Here is the key insight that makes this problem elegant. Any subarray of a circular array falls into one of two cases:

Case 1: The maximum subarray does not wrap around. It sits entirely within the linear array. This is exactly the classic maximum subarray problem, solved by Kadane's algorithm.

Case 2: The maximum subarray wraps around. It takes some elements from the end of the array and some from the beginning. Now think about what is left out. The excluded elements form a contiguous subarray in the middle of the array. If the wrapping subarray has the maximum sum, then the excluded middle part must have the minimum sum. So:

maxWrappingSum = totalSum - minSubarraySum

The answer is simply max(maxSubarraySum, totalSum - minSubarraySum).

But there is one edge case: if all elements are negative, minSubarraySum equals totalSum (the entire array is the minimum subarray). That would give us totalSum - totalSum = 0, which corresponds to an empty subarray, and the problem requires a non-empty subarray. In this case, we just return maxSubarraySum (the least negative element).

Algorithm

  1. Initialize maxSum = nums[0]minSum = nums[0]currentMax = 0currentMin = 0, and totalSum = 0.
  2. For each element in the array:
    1. currentMax = max(currentMax + nums[i], nums[i]) (Kadane's for max).
    2. Update maxSum = max(maxSum, currentMax).
    3. currentMin = min(currentMin + nums[i], nums[i]) (Kadane's for min).
    4. Update minSum = min(minSum, currentMin).
    5. Add nums[i] to totalSum.
  3. If maxSum < 0, return maxSum (all elements are negative).
  4. Otherwise, return max(maxSum, totalSum - minSum).

Example Walkthrough

1Initialize: currentMax=0, maxSum=5, currentMin=0, minSum=5, totalSum=0
0
5
1
-3
2
5
1/6

Code