Title: Find Longest Alternating Subarray
In this guide, you will learn how to find the longest alternating subarray inside an array of integers using Java. This is a classic array-scanning problem that shows up often in coding interviews because it tests whether you can track a changing condition across a sliding window without extra memory.
We will look at the problem definition, build a linear-time algorithm from scratch, trace it by hand on a sample array, and then walk through common mistakes and interview follow-up questions so you are fully prepared to discuss this problem out loud.
Understanding the Problem
You are given an array of non-negative integers called nums. A subarray is considered alternating if it has at least two elements and the difference between each pair of consecutive elements flips sign every step: the first difference must be +1, the second must be -1, the third must be +1, and so on.
Your task is to return the length of the longest subarray that satisfies this pattern. If no two consecutive elements ever differ by exactly 1, no alternating subarray exists, and the function should return -1 instead of 0, since 0 would be ambiguous with a valid answer.
Approach
- Initialize
maxLento-1and the starting pointerito0; this sentinel value signals that no alternating subarray was found if the array never produces one. - At each
i, check whethernums[i + 1] - nums[i]equals1; if it does not, moveiforward by one and try the next starting point. - When the first difference is
1, start extending a candidate run from indexi: setj = i + 1andexpectedDiff = -1. - Keep extending while
nums[j + 1] - nums[j]equalsexpectedDiff; each successful match flipsexpectedDiffbetween-1and1and advancesjby one. - Once the alternation breaks or the array ends, the run covers indices
ithroughj, so updatemaxLenwithj - i + 1if it is larger. - Set
i = jso the next outer-loop pass starts exactly where this run stopped, instead of skipping a potential new starting point. - Repeat these steps until
ireaches the second-to-last index, then returnmaxLen.
Java Program
public class LongestAlternatingSubarray {
public static int longestAlternatingSubarray(int[] nums) {
int n = nums.length;
int maxLen = -1;
int i = 0;
while (i < n - 1) {
if (nums[i + 1] - nums[i] != 1) {
i++;
continue;
}
int j = i + 1;
int expectedDiff = -1;
while (j < n - 1 && nums[j + 1] - nums[j] == expectedDiff) {
expectedDiff = -expectedDiff;
j++;
}
maxLen = Math.max(maxLen, j - i + 1);
i = j;
}
return maxLen;
}
public static void main(String[] args) {
int[] nums = {4, 5, 4, 5, 6, 7, 2};
int result = longestAlternatingSubarray(nums);
System.out.println("Longest alternating subarray length: " + result);
}
}Explanation of the Program
The method longestAlternatingSubarray scans the array once with two pointers, i and j. The outer while loop picks a candidate starting index, and the inner while loop stretches that candidate as far as the alternating pattern allows.
maxLenstarts at-1so an array with no alternating pair correctly reports that no valid subarray was found.- The outer loop only enters the candidate-building block when
nums[i + 1] - nums[i] == 1, which is the required first step of every alternating run. expectedDiffstarts at-1because the second step of the pattern must be a decrease; it flips sign with-expectedDiffafter every successful match.- The inner loop condition
j < n - 1guards against readingnums[j + 1]past the end of the array. - After the inner loop stops, the run spans indices
ithroughjinclusive, so its length isj - i + 1. - Setting
i = jinstead ofi = j + 1lets the next outer-loop pass reconsider indexjas a fresh starting point, since the diff that broke the pattern might itself be+1.
Step-by-Step Trace
Consider nums = {1, 2, 1, 2, 3, 4, 2}, where the correct answer is 4. The table below follows the outer loop pointer i through every pass, showing how far each candidate run extends and how maxLen changes.
| i | nums[i+1] - nums[i] | Run ends at j | Run length (j - i + 1) | maxLen before | maxLen after |
|---|---|---|---|---|---|
| 0 | 1 | 3 | 4 | -1 | 4 |
| 3 | 1 | 4 | 2 | 4 | 4 |
| 4 | 1 | 5 | 2 | 4 | 4 |
| 5 | -2 (not 1) | no run | - | 4 | 4 |
At the end of every outer-loop pass, maxLen holds the length of the longest alternating run found among all starting indices examined so far, which is why the final value returned once i reaches n - 1 is the answer for the whole array.
Examples
Example 1: A Strictly Increasing Array
When every element increases by more than one step, the only alternating runs possible are length-2 pairs, since the second required difference of -1 never appears.
int[] nums = {1, 2, 3, 4};
System.out.println(longestAlternatingSubarray(nums));
// Output: 2Example 2: No Alternating Subarray Exists
A strictly decreasing array never produces a first difference of +1, so the method should return -1 rather than 0.
int[] nums = {10, 9, 8, 7};
System.out.println(longestAlternatingSubarray(nums));
// Output: -1Example 3: Multiple Runs of Different Lengths
This array contains a long zigzag run followed by a short one, which demonstrates that the method keeps the maximum across every candidate it tries instead of returning as soon as one run ends.
int[] nums = {3, 4, 3, 4, 3, 4, 10, 11};
System.out.println(longestAlternatingSubarray(nums));
// Output: 6Common Mistakes to Avoid
These are the mistakes learners most often make when implementing this exact algorithm.
- Checking nums[j + 1] without a bound check - using
j < ninstead ofj < n - 1inside the inner loop throws anArrayIndexOutOfBoundsExceptionwhenjreaches the last index. Guard the inner loop withj < n - 1. - Forgetting to reset expectedDiff - reusing the value left over from the previous candidate run makes the next run's alternation check wrong from its very first comparison. Reset
expectedDiff = -1every time a new run starts. - Returning 0 for no match - returning
0when no alternating subarray exists is indistinguishable from a valid zero-length result and breaks any caller checking for failure. Return-1as the sentinel instead. - Advancing i past j - setting
i = j + 1after a run ends skips the possibility that indexjstarts a brand-new alternating run. Seti = jso that starting point is still considered. - Comparing diffs with Math.abs - using
Math.abs(nums[i + 1] - nums[i]) == 1wrongly accepts a first step of-1, which is not part of this problem's definition. Compare against the exact signed value,== 1for the first step and the signedexpectedDiffafterward.
Edge Cases to Test
Walk through these input shapes out loud before you consider the solution finished.
- Empty array
- Single-element array
- Two-element array with a diff of exactly 1
- Strictly decreasing array (no diff of +1 anywhere)
- All elements identical
- Alternating run that spans the entire array
- Multiple runs of equal maximum length at different positions
- Integer.MIN_VALUE or Integer.MAX_VALUE present (overflow risk in the subtraction)
Additional Considerations
The algorithm runs in O(n) time. Although there are two nested while loops, the outer loop always resumes from where the inner loop stopped with i = j, so no index is revisited more than once across the whole scan; the total work is linear in the size of nums.
Space usage is O(1) since the method only tracks a handful of integer variables regardless of input size. The one subtlety worth testing is overflow: if nums can contain values near Integer.MIN_VALUE or Integer.MAX_VALUE, the subtraction nums[i + 1] - nums[i] can overflow a 32-bit int, so for untrusted input ranges consider casting to long before subtracting.
Interview Follow-up Questions
An interviewer will often extend this problem once you have the base solution working.
- What if the array is empty or has one element? - return
-1immediately, since no subarray of length greater than one can exist. - What if the numbers arrive as a stream of unknown length? - keep only the previous value, the current run's
expectedDiff, and the runningmaxLenin memory, and update them as each new number arrives instead of storing the whole array. - What if you need the start and end indices of the longest run, not just its length? - store
bestStartandbestEndalongsidemaxLenand update all three together whenever a longer run is found. - What if the first step of the pattern could be either +1 or -1? - run the scan twice, once requiring the first difference to be
+1and once requiring-1, and return the larger of the two results. - What if nums has billions of elements and must be processed across multiple machines? - split the array into contiguous chunks, run the scan on each chunk independently, then merge results at chunk boundaries by checking whether the run at the end of one chunk continues into the start of the next.
Conclusion
Finding the longest alternating subarray comes down to recognizing that each valid run has a strict signed pattern, and that a single forward pass with two pointers is enough to find the longest one in linear time. The trickiest parts are the sentinel return value of -1 and making sure the next candidate run starts at exactly the right index.
Try adapting this same two-pointer, pattern-matching approach to other array problems that ask for the longest run satisfying some condition, such as the longest strictly increasing subarray or the longest subarray with alternating parity. You can learn more about array-based interview problems like this one: https://dailyjavaconcept.com/category/arrays/



