Published in

solvingalgo

Problem

`Find the contiguous subarray within an array (containing at least one number) which has the largest sum.For example given the array [-2, 1,-3, 4, -1, 2, 1, -5, 4], the contiguous subarray [4, -1, 2, 1] has the largest sum = 6.For this problem, return the maximum sum.`

Solving Process

Brute Force Solution

If we don’t take enough time to think about the fundamentals of this problem, the first solution we may think of is the brute force one.

The idea would simply be to test a subarray by removing either the first or the last element.

To avoid having to compute each time the sum of a subarray, we could keep a count variable initialized from the initial array and updated throughout the algorithm.

First, we need a function to compute the sum of all elements in an array:

The core algorithm could be implemented both iteratively or recursively. For the sake of this example, let’s implement it using recursion:

At the end of the function, we return the maximum value between:

• The current count
• The subarray without the first element
• The subarray without the last element

Let’s take a look at the time complexity. For each element, we recurse two times. This means the time complexity is O(2^n). Indeed, the time complexity of a recursive function that makes multiple calls is O(b^depth) with b the number of times each recursive call branches. Meanwhile, the space complexity is O(n) due to the recursive implementation.

This complexity may remind us of the basic Fibonacci problem which can be efficiently solved using dynamic programming. Yet, in this case, it is not necessary to implement something that complex.

Let’s take a closer look at the problem and see if we were not missing something.

Let’s take a concrete example with the following input:

`4, -1, 6, -100, 5`

Here, we can directly say the maximum sum is 9. But what’s the reason to keep -1 but not -100 in the maximum subarray? Obviously, because in this context, keeping -100 would just reduce the maximum possible sum.

The solution is to keep a counter and to increment it with each element. If at some point the counter is negative, there is no need to keep track of the past. We erase the counter and we just move on to the next element. This solution is known as the Kadane’s algorithm.

Let’s see a possible implementation in Java:

As we can see, the solution is very simple but simplicity comes with practice. However, it was absolutely mandatory to understand the fundamentals of the problem to solve it.