Calculating and improving time and memory complexity
It is possible to make it much more efficient by using a completely different algorithm. The idea is to take a closer look at prefix sums. Let's assume that a subarray [L, R] is divisible by 3. It means that prefixSum[R] - prefixSum[L - 1] == 0 (mod 3), or prefixSum[R] == prefixSum[L - 1] (mod 3). It results in a simple solution: iterating over all elements of the array from left to right and maintaining the current prefix sum modulo 3 and keeping track of the first occurrence of each value modulo 3. The code can look like this:

int getLongestSubarray(int[] a) {
    int[] firstOccurrence = new int[3];
    firstOccurrence[0] = -1;
    firstOccurrence[1] = a.length;
    firstOccurrence[2] = a.length;
    int prefixSum = 0;
    int result = 0;
    for (int i = 0; i &lt; a.length; i++) {
        prefixSum = (prefixSum + a[i]) % 3;
        if (prefixSum &lt; 0)
            prefixSum += 3;
        result = Math.max(result, i - firstOccurrence[prefixSum]);
        firstOccurrence[prefixSum] = Math.min(firstOccurrence[prefixSum], i);
    }
    return result;
}


The time complexity is O(n) and the space complexity is O(1). It is optimal because it is not possible to find the longest subarray divisble by 3 without seeing all elements of the input array.