006. Longest Positive Streak
Problem
Return the length of the longest contiguous run of strictly positive integers. Zero and negative values break a run. Empty input and an input with no positive value return zero. A run consists of adjacent positions, not a subsequence chosen by skipping failures.
Examples
Example 1
positive_streak([-1, 2, 3, -2, 4])
=> 2The final run is shorter than the earlier run.
Example 2
positive_streak([])
=> 0There is no nonempty run.
Example 3
positive_streak([1, 0, 2, 3])
=> 2Zero breaks the first run.
Reveal the worked solution and reasoning
Why this mechanism works
Separate the run that is still alive from the best completed or ongoing run. The current run has only two possible transitions: extend on a positive event, or reset on a break. The global best is updated after that transition so a run ending at the final element is included.
State and boundaries
current is the positive suffix length of the processed prefix. best is the largest such suffix observed so far.
Protocol
- Initialize current and best to zero.
- Extend current for a positive value.
- Otherwise reset current to zero.
- Update best from current after the branch.
- Return best.
Visualization
values: -1 2 3 -2 4
current: 0 1 2 0 1
best: 0 1 2 2 2Python implementation
def positive_streak(nums):
current = best = 0
for value in nums:
current = current + 1 if value > 0 else 0
best = max(best, current)
return best
Worked execution
positive_streak([-1, 2, 3, -2, 4])
L2 positive_streak: current = best = 0 nums=[-1, 2, 3, -2, 4]; current=0; best=0 L3 positive_streak: for value in nums: nums=[-1, 2, 3, -2, 4]; current=0; best=0; value=-1 L3 positive_streak: for value in nums: nums=[-1, 2, 3, -2, 4]; current=0; best=0; value=2 L4 positive_streak: current = current + 1 if value > 0 else 0 nums=[-1, 2, 3, -2, 4]; current=1; best=0; value=2 L5 positive_streak: best = max(best, current) nums=[-1, 2, 3, -2, 4]; current=1; best=1; value=2 L3 positive_streak: for value in nums: nums=[-1, 2, 3, -2, 4]; current=1; best=1; value=3 L4 positive_streak: current = current + 1 if value > 0 else 0 nums=[-1, 2, 3, -2, 4]; current=2; best=1; value=3 L5 positive_streak: best = max(best, current) nums=[-1, 2, 3, -2, 4]; current=2; best=2; value=3 L3 positive_streak: for value in nums: nums=[-1, 2, 3, -2, 4]; current=2; best=2; value=-2 L4 positive_streak: current = current + 1 if value > 0 else 0 nums=[-1, 2, 3, -2, 4]; current=0; best=2; value=-2 L3 positive_streak: for value in nums: nums=[-1, 2, 3, -2, 4]; current=0; best=2; value=4 L4 positive_streak: current = current + 1 if value > 0 else 0 nums=[-1, 2, 3, -2, 4]; current=1; best=2; value=4
Result: 2. The final run is shorter than the earlier run.
positive_streak([])
L2 positive_streak: current = best = 0 nums=[]; current=0; best=0
Result: 0. There is no nonempty run.
Why the solution is correct
A positive value extends exactly the preceding positive suffix; a nonpositive value leaves no positive suffix. Every maximal positive run appears as current at its final index. Taking the maximum of these suffix lengths finds the longest run.
Time and space
O(n) time and O(1) auxiliary space.
Common mistakes
Resetting best destroys earlier successful runs. Counting all positive values ignores contiguity.
Reasoning card
State: current is the positive suffix length of the processed prefix. best is the largest such suffix observed so far.
Invariant: current is the positive streak ending at the current value.
Decision to rehearse: Extend or reset, then update the global best.
Finish: Return best
Transfer exercise
Return the first longest run's half-open interval as well as its length.