# Maximum subarray problem

Visualization of how sub-arrays change based on start and end positions of a sample. Each possible contiguous sub-array is represented by a point on a colored line. That point's y-coordinate represents the sum of the sample. Its x-coordinate represents the end of the sample, and the leftmost point on that colored line represents the start of the sample. In this case, the array from which samples are taken is [2, 3, -1, -20, 5, 10].

In computer science, the maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array, a[1...n], of numbers which has the largest sum, where, for ${\displaystyle 1\leq i\leq j\leq n}$,

${\displaystyle M=\max(L),\quad L={\sum _{x=i}^{j}}a[x]}$

The list usually contains both positive and negative numbers along with 0. For example, for the array of values −2, 1, −3, 4, −1, 2, 1, −5, 4; the contiguous subarray with the largest sum is 4, −1, 2, 1, with sum 6.

Some properties of this problem are:

1. If the array contains all non-positive numbers, then the solution is the number in the array with the smallest magnitude.
2. If the array contains all non-negative numbers, then the problem is trivial and the maximum sum is the sum of all the elements in the list.
3. An empty set[clarification needed] is not valid.
4. There can be multiple different sub-arrays that achieve the same maximum sum to the problem.

There will be discussions on different algorithm techniques that are used to solve this problem which include: brute force algorithm, divide and conquer, and dynamic programming. This analysis will compare the time complexity of the different algorithms for the MSP.

## History

The problem was first posed by Ulf Grenander of Brown University in 1977 as a simplified model for maximum likelihood estimation of patterns in digitized images. Grenander was looking to find the maximum sum of an m * n rectangular region of real numbers. He designed an algorithm that ran in O(n6) time. His algorithm was too slow and the problem was too complex to be solved, so he simplified it to one dimension. This made the problem easier to comprehend and as a result, he was able to solve the original problem with a faster running time of O(n3). Jay Kadane of Carnegie Mellon University (Bentley 1984) soon after designed a linear time algorithm.[clarification needed]

Algorithms to solve a two dimensional version of the problem were later designed and run in O(n3) time,[clarification needed] using Kadane's algorithm or a divide and conquer approach. Overall the optimal running time for a one dimensional array is O(n), while the two dimensional array has been improved to a sub-cubic time by the efforts of Tamaki and Tokuyama.[1]

Using the Bird–Meertens formalism, an O(n) algorithm has been derived by algebraic manipulation of the brute-force algorithm in a functional programming language.[2]

## Applications

Maximum subarray algorithms are used for data analysis in many fields, such as genomic sequence analysis, computer vision, and data mining.

Genomic sequence analysis employs maximum subarray algorithms to identify important biological segments of protein sequences and the information for the purpose of predicting outcomes[clarify]. As an example, specific information of a protein sequence can be organized into a linear function which can be used to understand the structure and function of a protein.[clarify] Biologists find this approach to be efficient and easy to analyze their data.[weasel words]

The score-based technique of finding the segment with the highest total sum is used in many problems similar to the MSP. In genomic sequence analysis, these problems include conserved segments, GC-rich regions, tandem repeats, low-complexity filter, DNA binding domains, and regions of high charge.[citation needed]

For computer vision , maximum subarray algorithms are used in bitmap images to detect the highest score subsequence which represents the brightest area in an image. The image is a two dimensional array of positive values that corresponds to the brightness of a pixel. The algorithm is evaluated after normalizing every value in the array by subtracting them from the mean brightness.

Data mining is an application of maximum subarray algorithms with numerical attributes. To understand the role of the maximum subarray problem in data mining it is important to be familiar with the association rule and its parts. The association rule is an if/then statement that creates relationships between unrelated pieces of data. The two parts of the association rule are the antecedent (if statement) and the consequent (then statement). In business applications of data mining, association rules are important in examining and foreseeing customer's actions/behavior. Data mining is used for companies to anticipate common trends, by representing problems with maximum subarray problem into an sub-array to be normalized and solved. The highest result[clarify] of the array will give companies information of what customers are responding well to and will influence the companies' actions as a result.[citation needed]

A bit of a background: Kadane's algorithm is based on splitting up the set of possible solutions into mutually exclusive (disjoint) sets. It exploits the fact that any solution (i.e., any member of the set of solutions) will always have a last element ${\displaystyle i}$ (this is what is meant by "sum ending at position ${\displaystyle i}$"). Thus, we simply have to examine, one by one, the set of solutions whose last element's index is ${\displaystyle 1}$, the set of solutions whose last element's index is ${\displaystyle 2}$, then ${\displaystyle 3}$, and so forth to ${\displaystyle n}$. It turns out that this process can be carried out in linear time.

Kadane's algorithm begins with a simple inductive question: if we know the maximum subarray sum ending at position ${\displaystyle i}$ (call this ${\displaystyle B_{i}}$), what is the maximum subarray sum ending at position ${\displaystyle i+1}$ (equivalently, what is ${\displaystyle B_{i+1}}$)? The answer turns out to be relatively straightforward: either the maximum subarray sum ending at position ${\displaystyle i+1}$ includes the maximum subarray sum ending at position ${\displaystyle i}$ as a prefix, or it doesn't (equivalently, ${\displaystyle B_{i+1}=max(A_{i+1},A_{i+1}+B_{i})}$, where ${\displaystyle A_{i+1}}$ is the element at index ${\displaystyle i+1}$).

Thus, we can compute the maximum subarray sum ending at position ${\displaystyle i}$ for all positions ${\displaystyle i}$ by iterating once over the array. As we go, we simply keep track of the maximum sum we've ever seen. Thus, the problem can be solved with the following code, expressed here in Python:

1 def max_subarray(A):
2     max_ending_here = max_so_far = A[0]
3     for x in A[1:]:
4         max_ending_here = max(x, max_ending_here + x)
5         max_so_far = max(max_so_far, max_ending_here)
6     return max_so_far


Note: with a bit of reasoning you will see that max_so_far is equal to ${\displaystyle max(B_{0},B_{1},B_{2},...,B_{i})}$.

The algorithm can also be easily modified to keep track of the starting and ending indices of the maximum subarray (when max_so_far changes) as well as the case where we want to allow zero-length subarrays (with implicit sum 0) if all elements are negative.

Because of the way this algorithm uses optimal substructures (the maximum subarray ending at each position is calculated in a simple way from a related but smaller and overlapping subproblem: the maximum subarray ending at the previous position) this algorithm can be viewed as a simple/trivial example of dynamic programming.

The runtime complexity of Kadane's algorithm is ${\displaystyle O(n)}$.

## Generalizations

Similar problems may be posed for higher-dimensional arrays, but their solutions are more complicated; see, e.g., Takaoka (2002). Brodal & Jørgensen (2007) showed how to find the k largest subarray sums in a one-dimensional array, in the optimal time bound ${\displaystyle O(n+k)}$.

The Maximum sum k-disjoint subarrays can also be computed in the optimal time bound ${\displaystyle O(n+k)}$ .[3]