Search the subarray with the maximum/minimum sum¶
Here, we consider the problem of finding a subarray with maximum sum, as well as some of its variations (including the algorithm for solving this problem online).
Problem statement¶
Given an array of numbers
For example, if all integers in array
It is clear that the problem of finding the minimum subarray is essentially the same, you just need to change the signs of all numbers.
Algorithm 1¶
Here we consider an almost obvious algorithm. (Next, we'll look at another algorithm, which is a little harder to come up with, but its implementation is even shorter.)
Algorithm description¶
The algorithm is very simple.
We introduce for convenience the notation:
Let us now iterate over the index
Formally, this means that for the current
From here, we immediately obtain a solution: we simply store where the current minimum is in the array
Obviously, this algorithm works in
Implementation¶
To implement it, we don't even need to explicitly store an array of partial sums
The implementation is given in 0-indexed arrays, not in 1-numbering as described above.
We first give a solution that finds a simple numerical answer without finding the indices of the desired segment:
int ans = a[0], sum = 0, min_sum = 0;
for (int r = 0; r < n; ++r) {
sum += a[r];
ans = max(ans, sum - min_sum);
min_sum = min(min_sum, sum);
}
Now we give a full version of the solution, which additionally also finds the boundaries of the desired segment:
int ans = a[0], ans_l = 0, ans_r = 0;
int sum = 0, min_sum = 0, min_pos = -1;
for (int r = 0; r < n; ++r) {
sum += a[r];
int cur = sum - min_sum;
if (cur > ans) {
ans = cur;
ans_l = min_pos + 1;
ans_r = r;
}
if (sum < min_sum) {
min_sum = sum;
min_pos = r;
}
}
Algorithm 2¶
Here we consider a different algorithm. It is a little more difficult to understand, but it is more elegant than the above, and its implementation is a little bit shorter. This algorithm was proposed by Jay Kadane in 1984.
Algorithm description¶
The algorithm itself is as follows. Let's go through the array and accumulate the current partial sum in some variable
Proof:
Consider the first index when the sum of
However, this is not enough to prove the algorithm. In the algorithm, we are actually limited in finding the answer only to such segments that begin immediately after the places when
But, in fact, consider an arbitrary segment
One way or another, it turns out that when searching for an answer, you can limit yourself to only segments that begin immediately after the positions in which
Implementation¶
As in algorithm 1, we first gave a simplified implementation that looks for only a numerical answer without finding the boundaries of the desired segment:
int ans = a[0], sum = 0;
for (int r = 0; r < n; ++r) {
sum += a[r];
ans = max(ans, sum);
sum = max(sum, 0);
}
A complete solution, maintaining the indexes of the boundaries of the corresponding segment:
int ans = a[0], ans_l = 0, ans_r = 0;
int sum = 0, minus_pos = -1;
for (int r = 0; r < n; ++r) {
sum += a[r];
if (sum > ans) {
ans = sum;
ans_l = minus_pos + 1;
ans_r = r;
}
if (sum < 0) {
sum = 0;
minus_pos = r;
}
}
Related tasks¶
Finding the maximum/minimum subarray with constraints¶
If the problem condition imposes additional restrictions on the required segment
Two-dimensional case of the problem: search for maximum/minimum submatrix¶
The problem described in this article is naturally generalized to large dimensions. For example, in a two-dimensional case, it turns into a search for such a submatrix
Using the solution for the one-dimensional case, it is easy to obtain a solution in
Faster algorithms for solving this problem are known, but they are not much faster than
This algorithm by Chan, as well as many other results in this area, actually describe fast matrix multiplication (where matrix multiplication means modified multiplication: minimum is used instead of addition, and addition is used instead of multiplication). The problem of finding the submatrix with the largest sum can be reduced to the problem of finding the shortest paths between all pairs of vertices, and this problem, in turn, can be reduced to such a multiplication of matrices.
Search for a subarray with a maximum/minimum average¶
This problem lies in finding such a segment
Of course, if no other conditions are imposed on the required segment
In this case, we apply the standard technique when working with the problems of the average value: we will select the desired maximum average value by binary search.
To do this, we need to learn how to solve the following subproblem: given the number
To solve this subproblem, subtract
Thus, we obtained the solution for the asymptotic
Solving the online problem¶
The condition of the problem is as follows: given an array of
The algorithm for solving this problem is quite complex. KADR (Yaroslav Tverdokhleb) described his algorithm on the Russian forum.