`WeatherData` is #3 from the from the 2023 AP Computer Science A Free Response problems.

https://apcentral.collegeboard.org/media/pdf/ap23-frq-comp-sci-a.pdf

Part (a) `cleanData` method

``````public void cleanData(double lower, double upper)
{
int i = 0;

while(i < temperatures.size())
{
Double t = temperatures.get(i);

if(t.compareTo(lower) < 0 || t.compareTo(upper) > 0)
temperatures.remove(i);
else
i++;
}
}
``````

The use of `compareTo` is optional. Java will automatically unbox the `Double` objects into `double`.

Part (b) `longestHeatWave` method (original solution)

``````public int longestHeatWave(double threshold)
{
int almostCurrentLength = 0;
int almostMaxLength = 0;

for(int i = 1; i < temperatures.size(); i++)
{
Double before = temperatures.get(i - 1);
Double current = temperatures.get(i);

if(before.compareTo(threshold) > 0 &&
current.compareTo(threshold) > 0)
{
// in heatwave
almostCurrentLength++;

if(almostCurrentLength > almostMaxLength)
almostMaxLength = almostCurrentLength;
}
else
almostCurrentLength = 0;
}

return almostMaxLength + 1;
}
``````

`almostCurrentLength` stores 1 less than the length of the heatwave that includes the element at `i`, or `0` if the element at `i` is not the second or subsequent element of a heatwave. (`almostCurrentLength` excludes the first element of the heatwave.)

`almostMaxLength` stores 1 less than the length of the longest known heatwave, or `0` if a heatwave has not yet been encountered.

This is a variation of find the minimum or maximum. `almostMaxLength` starts at `0` because no heatwave has yet been encountered. (It is also possible to start `almostMaxLength` at `1` since the problem description guarantees at least 1 heatwave.) The length of each heatwave encountered is compared against the length of the longest known heatwave.

When I originally approached this problem, I thought of it as being similar to the NumberCube `getLongestRun` method. My original solution to `longestHeatWave` is based on updating `almostCurrentLength` if and only if the value at `i` is part of a heatwave. This requires comparing consecutive elements and addressing skipping the first element of each heatwave. The additional solution below is more straightforward.

Part (b) `longestHeatWave` method (additional solution)

``````public int longestHeatWave(double threshold)
{
int hotInARow = 0;
int maxHotInARow = 0;

for(int i = 0; i < temperatures.size(); i++)
{
if(temperatures.get(i).compareTo(threshold) > 0)
{
hotInARow++;

if(hotInARow > maxHotInARow)
maxHotInARow = hotInARow;
}
else
hotInARow = 0;
}

return maxHotInARow;
}
``````

As others (too many to credit) have pointed out, it is not necessary to compare consecutive elements within a single run of the loop. This solution finds the length of the longest run of days that exceed `threshold`, even if that length is 0 or 1. The problem guarantees that at least 1 heatwave exists, so the length of the longest run will always be `>= 2`.

Java files with test code

ThreeTest.java includes JUnit 5 test code with the examples from the problem and 1 additional easily missed example (longest heatwave is at the end). See Running JUnit 5 tests.