Maximum Sum Circular Subarray

MediumArrays · Kadane’s Algorithm🧩 Kadane's Running BestLeetCode #918 ↗Updated

Problem

You get an integer array nums that is treated as a ring: the element after the last one is the first one again. Return the largest possible sum of a non-empty contiguous piece of this ring, where each position may be used at most once (a piece can wrap around the end, but cannot be longer than n).
Input[1,-2,3,-2]Output3
Input[5,-3,5]Output10 (wraps: 5 + 5)
Input[-3,-2,-3]Output-2

1 ≤ n ≤ 3·104  ·  -3·104 ≤ nums[i] ≤ 3·104

Try it yourself

Java
class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
A wrapping piece is the whole ring minus a normal (non-wrapping) middle piece. So the best wrapping sum = total − minimum subarray sum; run Kadane twice (max and min) and take the better answer.
PatternKadane's Running Best

Instinct Best sum or product of a contiguous subarray in one pass? At each index choose - extend the run ending here or restart - and track the global best.

Memory hack Carry the bag only while it helps - a negative past is dead weight, drop it and restart here.

Open the Kadane's Running Best guide →

Approaches

Brute ForceTry Every Start and Length

Time O(n²)Space O(1)

Fix a starting index, then grow the piece one step at a time for up to n elements, reading nums[(start + len) % n]. The running sum is extended in O(1), so every one of the n² pieces is scored.

Java
public int maxSubarraySumCircular(int[] nums) {
    int n = nums.length;
    int best = Integer.MIN_VALUE;
    for (int start = 0; start < n; start++) {
        int sum = 0;
        // grow the piece clockwise, at most n elements
        for (int len = 0; len < n; len++) {
            sum += nums[(start + len) % n];
            best = Math.max(best, sum);
        }
    }
    return best;
}

Correct and simple, but quadratic — too slow at n = 3·104 in tight limits.

At a glance

LevelApproachTimeSpace
Brute ForceTry Every Start and LengthO(n²)O(1)
BetterKadane + Best Prefix / Suffix SplitO(n)O(n)
OptimalDouble Kadane (Total − Min Subarray)O(n)O(1)
Common pitfalls
  • Returning total − minSum when all numbers are negative — that is the empty piece (0).
  • Concatenating the array and running Kadane — allows pieces longer than n.
  • Initialising maxSum to 0 — wrong for all-negative input.
Interview tips
  • Split the cases: the answer either wraps or it doesn’t.
  • Draw the ring: a wrapping piece is the complement of a middle piece.
  • Mention the prefix/suffix version as a stepping stone if the complement trick doesn’t click.
Pattern
Kadane + complement → circular max-subarray problems: best wrap = total minus worst middle.
My notes saved in this browser