If a[] is an array with length N (i.e., N = a.length), then, for any pair of integers (k,m) satisfying 0≤k≤m≤N, a[k..m) refers to the portion of a[] beginning at location k and extending up to, but not including, location m. We refer to this as an array segment. A special case of an array segment is the whole array: take k to be 0 and m to be N. Another special case is an empty segment: take k and m to be equal. (Indeed, one can interpret it to be that each of a[0..0), a[1..1), ..., a[N..N) is a distinct empty segment of a!)
Of course, an array segment has subsegments. Specifically, if a[k..m) is an array segment, then, for any pair (k',m') satisfying k≤k'≤m'≤m, a[k'..m') is a subsegment of a[k..m). A special case of a subsegment is a prefix: a[k'..m') is a prefix of a[k..m) if k' = k. An analogous special case is a suffix: a[k'..m') is a suffix of a[k..m) if m' = m.
Now, if a[k..m) is a segment of an array that contains values of a numeric type (e.g., int, double, or even Integer), it makes sense to refer to its sum, meaning the sum of the elements that it contains: a[k] + a[k+1] + ... + a[m-1].
The Maximum Segment Sum problem is this: Given an array segment (possibly an entire array), determine the maximum among the sums of all its subsegments.
For example, consider the array a[] pictured below. Among all its segments, the largest sum achieved by any of them is 16. Indeed, there are four segments having that sum: a[2..8), a[5..8), a[12..16), and a[18..22).
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3 | -8 | 5 | 1 | -6 | 12 | -5 | 9 | -2 | -10 | 0 | -8 | 3 | 5 | -2 | 10 | -7 | -9 | 2 | 10 | -5 | 9 | -13 | 5 | 2 | -3 |
Given are the following Java classes:
Your task is to complete the stubbed maxSegSumRec() method in the given MaxSegSum class so that it satisfies its specification, which is to compute, with respect to a given array segment, the maximum among the sums of all its subsegments. (Of course, you are free to introduce private methods in support of the method to be completed; indeed, two such stubbed methods are already declared.)
There is a nice recursive algorithm for computing the maximum sum among all (sub)segments of an array segment. You are to implement that algorithm in the stubbed maxSegSum() method. It is based upon these observations:
The maximum sum among the subsegments of a[k..r) can be computed recursively, as can the maximum sum among the subsegments of a[r..m). As for the spanning subsegments, the maximum sum among them is obtained by adding the maximum among the sums of the suffixes of a[k..r) to the maximum among the sums of the prefixes of a[r..m).
Having computed these three values, we simply take the maximum of the three to give us the maximum sum of all subsegments of a[k..m).
For purposes of efficiency, we would choose r to be (k+m)/2, so that a[k..r) and a[r..m) were as close in length as possible.
Referring to our example array, repeated below, note that two of the segments with maximum sum are in the "left" half of the array (namely, a[2..8] and a[5..8)), one is in the "right" half (namely, a[18..22)), and one (a[12..16)) is a spanning segment.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
3 | -8 | 5 | 1 | -6 | 12 | -5 | 9 | -2 | -10 | 0 | -8 | 3 | 5 | -2 | 10 | -7 | -9 | 2 | 10 | -5 | 9 | -13 | 5 | 2 | -3 |