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.

WeatherData.java
ThreeTest.java

Additional resources

2023 AP CS Exam Free Response Solutions

Help & comments

Get help from AP CS Tutor Brandon Horn

Comment on WeatherData