007. Longest Alternating-Parity Streak
Problem
Return the longest contiguous run in which every adjacent pair has different parity. Odd and even are defined by value % 2, including negative integers. A singleton is a valid run of length one. Empty input returns zero.
Examples
Example 1
alternating_parity([1, 2, 5, 8, 10])
=> 4The final even-even edge breaks the run.
Example 2
alternating_parity([])
=> 0No singleton exists.
Example 3
alternating_parity([-3, -2, -1])
=> 3Negative values have usable parity too.
Reveal the worked solution and reasoning
Why this mechanism works
The condition belongs to an edge between neighboring values. When an edge fails, the current element remains a valid singleton even though it cannot extend the previous run. That is why a failed edge restarts the state at one rather than zero.
State and boundaries
current is the alternating suffix ending at the current index. best is the maximum suffix length seen.
Protocol
- Handle the empty list.
- Seed a singleton run.
- Compare each value's parity with its predecessor.
- Extend on different parity, otherwise restart at one.
- Update the best length.
Visualization
values: 1 2 5 8 10
parity: O E O E E
length: 1 2 3 4 1Python implementation
def alternating_parity(nums):
if not nums:
return 0
current = best = 1
for i in range(1, len(nums)):
if nums[i] % 2 != nums[i - 1] % 2:
current += 1
else:
current = 1
best = max(best, current)
return best
Worked execution
alternating_parity([1, 2, 5, 8, 10])
L2 alternating_parity: if not nums: nums=[1, 2, 5, 8, 10] L4 alternating_parity: current = best = 1 nums=[1, 2, 5, 8, 10]; current=1; best=1 L5 alternating_parity: for i in range(1, len(nums)): nums=[1, 2, 5, 8, 10]; current=1; best=1; i=1 L7 alternating_parity: current += 1 nums=[1, 2, 5, 8, 10]; current=2; best=1; i=1 L10 alternating_parity: best = max(best, current) nums=[1, 2, 5, 8, 10]; current=2; best=2; i=1 L5 alternating_parity: for i in range(1, len(nums)): nums=[1, 2, 5, 8, 10]; current=2; best=2; i=2 L7 alternating_parity: current += 1 nums=[1, 2, 5, 8, 10]; current=3; best=2; i=2 L10 alternating_parity: best = max(best, current) nums=[1, 2, 5, 8, 10]; current=3; best=3; i=2 ... 1 intermediate state changes omitted ... L7 alternating_parity: current += 1 nums=[1, 2, 5, 8, 10]; current=4; best=3; i=3 L10 alternating_parity: best = max(best, current) nums=[1, 2, 5, 8, 10]; current=4; best=4; i=3 L5 alternating_parity: for i in range(1, len(nums)): nums=[1, 2, 5, 8, 10]; current=4; best=4; i=4 L9 alternating_parity: current = 1 nums=[1, 2, 5, 8, 10]; current=1; best=4; i=4
Result: 4. The final even-even edge breaks the run.
alternating_parity([])
L2 alternating_parity: if not nums: nums=[]
Result: 0. No singleton exists.
Why the solution is correct
The first singleton satisfies the contract. A differing parity creates a valid extension of the longest alternating suffix; matching parity makes every longer suffix invalid while leaving the singleton valid. Every candidate run is considered at its endpoint.
Time and space
O(n) time and O(1) auxiliary space.
Common mistakes
Checking signs instead of parity changes the problem. A reset to zero undercounts a new run beginning at the failed edge's right endpoint.
Reasoning card
State: current is the alternating suffix ending at the current index. best is the maximum suffix length seen.
Invariant: current is the valid streak ending at the current element.
Decision to rehearse: A broken streak restarts at length one, not zero.
Finish: Update the best length
Transfer exercise
Replace alternating parity with a fixed adjacent difference. Which state and reset rule survive unchanged?