Python 2765.py
class Solution:
def alternatingSubarray(self, nums: List[int]) -> int:
diff = []
for i in range(1, len(nums)):
diff.append(nums[i] - nums[i - 1])
result = -1
for left in range(len(diff)):
if diff[left] != +1:
continue
expect = -1
length = 2
for right in range(left + 1, len(diff)):
if diff[right] != expect:
break
length += 1
expect = -expect
result = max(result, length)
return result
Difficulty
and has an acceptance rate of about 36% (90k+ submissions).
Typical patterns to solve this problem:
- Array
- Enumeration
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The alternatingSubarray method receives a list of integers and searches for the longest contiguous segment whose successive differences alternate strictly between +1 and -1. A segment of length two is the smallest candidate because a single element does not produce a difference. If no such segment exists the function returns -1. The implementation first converts the original list into a list of adjacent differences, then iterates over possible start positions, extending each candidate while the alternating pattern holds, and finally records the maximum length found.
Key Steps
Building the Difference Array
diff = []
for i in range(1, len(nums)):
diff.append(nums[i] - nums[i - 1])
This loop creates diff, where each entry represents the change from one element to the next. By working with differences the algorithm can focus on the required +1 / -1 pattern without repeatedly accessing the original list.
Scanning for Alternating Patterns
result = -1
for left in range(len(diff)):
if diff[left] != +1:
continue
expect = -1
length = 2
for right in range(left + 1, len(diff)):
if diff[right] != expect:
break
length += 1
expect = -expect
result = max(result, length)
The outer loop selects each possible start index left. The early continue discards any start where the first required difference (+1) is missing, saving work. The inner loop walks forward with index right, checking that each subsequent difference matches the expected sign (expect). When a mismatch occurs the inner loop stops, because the alternating property can no longer be satisfied beyond that point. The variable length tracks the size of the current subarray, beginning at 2 because the first two elements already satisfy the +1 requirement. After each successful step expect flips sign, ensuring the strict alternation.
Updating the Result
result = max(result, length)
After each candidate segment finishes, the current length is compared with the best length seen so far. The use of max guarantees that result always holds the longest valid length discovered up to that moment.
Edge Cases Handled
When the input list contains fewer than two elements, the diff construction yields an empty list, causing the outer loop to execute zero times and leaving result at its initial value -1. This correctly signals that no alternating subarray can exist.
If the first difference of a potential segment is not +1, the continue statement skips the entire inner expansion for that start position, preventing false positives that might arise from a -1 leading difference.
The inner loop’s break statement stops the scan as soon as the alternating condition fails, which naturally handles cases where the pattern terminates early, such as a sequence like [3, 4, 5] where the differences are [1, 1].
When the list contains a long stretch of alternating differences, the algorithm continues extending length until the end of diff, thereby capturing the maximal possible segment without missing any trailing elements.
Performance Optimizations
Precomputing the diff list eliminates repeated subtraction inside the nested loops, turning each check into a simple integer comparison.
The early continue on a non-+1 start eliminates unnecessary inner-loop work for positions that cannot begin a valid alternating subarray, reducing the total number of iterations.
The inner loop stops immediately on the first mismatch via break, preventing further scanning of a segment that has already failed the alternating requirement.
All variables are plain integers, and the algorithm uses only the additional diff list whose size is linear in the input, keeping memory usage minimal while allowing fast sequential access.
ELI5 - Simplified Explanation
Imagine you have a long line of numbered building blocks. The goal is to find the longest stretch where the numbers wiggle up and down in a perfect pattern by one.
First, look at the blocks and figure out the gap between each neighbor. If you have a block that is five and the next one is six, the gap is one. If you have a block that is six and the next one is five, the gap is negative one. The code creates a list of these gaps to see how they change from one step to the next.
Next, go through the gaps to find where the pattern starts with a jump of one. Once that jump is found, look at the following gaps to see if they follow the rhythm of jumping down by one, then up by one, then down by one again. Keep track of how many blocks are in that specific matching section.
Compare every section found this way to keep track of the biggest one. It is just like counting how many blocks are in the longest train of wiggling numbers.
Code Quality
Complexity Analysis
As a rule of thumb, the maximum input size for one second execution time is
- factorial: up to 10 elements
- exponential: up to 20 elements
- polynomial: a few thousand elements
- loglinear: up to 100,000 elements
- linear: a few million elements
- logarithmic: a billion elements
- constant: practically unlimited
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||
|---|---|---|---|---|---|---|---|
| author | solutions | ||||||
| www | AlgoMonster | Java | C++ | Python | TS | ||
| WalkCCC | Java | C++ | Python | ||||
| leetcode.ca | Java | C++ | Go | Python | TS | ||
| Progiez | Java | C++ | Python | ||||
| github | charles-wangkai | Java | |||||
| fsq | Rust | ||||||
| varunu28 | Java | ||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||
| WalkCCC | C++, Python, Java | ||||||
| leetcode.ca | C++, Go, Java, Python, TypeScript | ||||||
| Progiez | C++, Java, Python | ||||||
| charles-wangkai | Java | ||||||
| fsq | Rust | ||||||
| varunu28 | Java |
Videos
Similar Problems
- problem 978: Longest Turbulent Subarray
Solved On The Same Day
- problem 859: Buddy Strings
- problem 914: X of a Kind in a Deck of Cards
- problem 925: Long Pressed Name
- problem 1346: Check If N and Its Double Exist
- problem 1805: Number of Different Integers in a String
- problem 1909: Remove One Element to Make the Array Strictly Increasing
- problem 2047: Number of Valid Words in a Sentence
- problem 2469: Convert the Temperature
- problem 2525: Categorize Box According to Criteria
- problem 2591: Distribute Money to Maximum Children
- problem 2614: Prime In Diagonal
- problem 2660: Determine the Winner of a Bowling Game
- problem 2760: Longest Even Odd Subarray With Threshold
- problem 1255: Maximum Score Words Formed by Letters
- problem 2251: Number of Flowers in Full Bloom
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality