import java.util.Arrays; /* Java class that includes methods for determining the maximum segment sum ** of an array (or segment thereof) containing int values. ** ** Author: R. McCloskey ** Date: January 2020 */ public class MaxSegSumViaPrefixSums implements MaxSegSum { // instance variables // ------------------ private int maxDiffSoFar; // result of most recent call to maxSegSum() private long workMeasure; // # calls and loop iterations since reset() // constructor // ----------- public MaxSegSumViaPrefixSums() { workMeasure = 0; maxDiffSoFar = -1; } // observer // -------- public int maxSegSumVal() { return maxDiffSoFar; } public long measureOfWork() { return workMeasure; } // mutators // -------- public void reset() { workMeasure = 0L; } /* Returns the maximum segment sum of the given array, computed using ** the prefix sums approach. */ public int maxSegSum(int[] a) { return maxSegSum(a, 0, a.length); } /* Returns the maximum segment sum of the given array segment ** (i.e., a[low..high)), computed using the prefix sums approach. ** pre: 0 <= low <= high <= a.length */ public int maxSegSum(int[] a, int low, int high) { int prefixSum = 0; int minPrefixSumSoFar = 0; maxDiffSoFar = 0; int i = low; // loop invariant: // prefixSum = sum of elements in a[low..i) and // minPrefixSumSoFar = minimum among sums of all prefixes of a[low..i) // maxDiffSoFar = difference between maximum of sums of prefixes of // of a[low..i) and minimum thereof while (i != high) { prefixSum = prefixSum + a[i]; int thisDiff = prefixSum - minPrefixSumSoFar; if (thisDiff >= maxDiffSoFar) { maxDiffSoFar = thisDiff; //System.out.println("new max difference at " + i); } if (prefixSum < minPrefixSumSoFar) { minPrefixSumSoFar = prefixSum; //System.out.println("new min prefix sum at " + i); } i = i+1; } workMeasure = workMeasure + high - low + 1; return maxDiffSoFar; } }