Last Updated: March 22, 2026
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:
The key question is: how do we efficiently handle the wrapping case without literally doubling the array and checking every possibility?
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.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.
maxSum to negative infinity.i from 0 to n-1:currentSum = 0.j from 0 to n-1:nums[(i + j) % n] to currentSum.maxSum = max(maxSum, currentSum).maxSum.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?
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).
The magic of this approach comes from a simple observation about complementary subarrays. In a circular array, any wrapping subarray and the elements it skips are complementary: together they cover the entire array. So if we want to maximize the wrapping sum, we need to minimize the sum of the skipped elements. That is exactly what Kadane's algorithm for minimum subarray gives us.
By running Kadane's twice in one pass (once for max, once for min), we cover both cases in O(n) time. The only subtlety is the all-negatives edge case, where the "minimum subarray" is the entire array, and subtracting it would give an empty subarray sum of 0. Since the problem requires a non-empty subarray, we fall back to the standard maximum subarray answer in that case.
maxSum = nums[0], minSum = nums[0], currentMax = 0, currentMin = 0, and totalSum = 0.currentMax = max(currentMax + nums[i], nums[i]) (Kadane's for max).maxSum = max(maxSum, currentMax).currentMin = min(currentMin + nums[i], nums[i]) (Kadane's for min).minSum = min(minSum, currentMin).nums[i] to totalSum.maxSum < 0, return maxSum (all elements are negative).max(maxSum, totalSum - minSum).