Optimize the code · Medium

Speed Up Maximum Subarray

Medium Make it fast Most askedSeen at Amazon, Microsoft, LinkedIn

maxSubArray(nums) returns the largest sum of any non-empty contiguous subarray.

The code below tries every start position and extends to the right. It is correct and quadratic. Make it O(n) without changing the results.

Example 1

Input: nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
Output: 6
Explanation: [4, -1, 2, 1] has the largest sum.

Example 2

Input: nums = [-3, -1, -2]
Output: -1

The slow code

Every case must finish within 300 ms (budgets are per language in the editor).

function maxSubArray(nums) {
  let best = -Infinity;
  for (let i = 0; i < nums.length; i++) {
    let sum = 0;
    for (let j = i; j < nums.length; j++) {
      sum += nums[j];
      if (sum > best) best = sum;
    }
  }
  return best;
}

Hints

Hint 1

What is the best sum of a subarray that ends at index i?

Hint 2

Either extend the best subarray ending at i - 1, or start fresh at i.

Make it faster

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the solution

Time O(n) · Space O(1)

Why it is slow: every start position is extended to the end of the array: n(n+1)/2 additions, 1.8 billion for 60,000 numbers.

The fix (Kadane's algorithm): keep cur, the best sum of a subarray ending at the current index: cur = max(x, cur + x). A negative running sum can never help what comes next, so it is dropped. The answer is the maximum cur seen. One pass, O(1) memory.

Initialise with the first element (not 0) so all-negative arrays return their largest element.

Optimized solution

function maxSubArray(nums) {
  let cur = nums[0]; // best sum of a subarray ending here
  let best = nums[0];
  for (let i = 1; i < nums.length; i++) {
    cur = Math.max(nums[i], cur + nums[i]);
    best = Math.max(best, cur);
  }
  return best;
}

Common mistakes

  • Initialising best = 0: wrong for all-negative input.
  • Resetting cur to 0 after updating best in the wrong order.

Follow-up questions

  • Return the start and end indices too.
  • Circular array version (maximum circular subarray).