Longest Turbulent Subarray
The drill: Find the longest run of consecutive elements where the comparisons zig-zag — each step must flip between climbing and dropping compared to the step before. A flat or repeated direction ends the run.
An array of integers arrives, and the goal is measuring the longest contiguous stretch where consecutive comparisons strictly alternate between climbing and dropping — up, then down, then up again, with no two same-direction steps back to back.
A stretch of just one element always counts as turbulent on its own, since there's no comparison yet to break. The moment two consecutive elements are equal, or the direction repeats instead of flipping, that particular run ends there.
Only the length of the longest such alternating stretch is needed, not its starting position or the actual values inside it.
- the array always holds at least one element
- values can repeat, including exact ties between neighbors
- a single element alone always counts as a turbulent run of length one
- only the longest run's length is reported, not its position
HINT 1 THE NUDGE
Checking every subarray for the alternating pattern directly re-examines the whole run each time. What could you carry forward from position i to i+1 instead of re-scanning from the start?
HINT 2 THE STRUCTURE
At each position ask only one thing: does this step continue an alternation that the OTHER direction left off, or does it break it? Two small numbers — the best run ending here going up, and the best run ending here going down — are enough to answer that.
HINT 3 ONE STEP FROM THE ANSWER
up[i] = down[i-1] + 1 when arr[i] > arr[i-1] (otherwise reset to 1); down[i] mirrors it for arr[i] < arr[i-1]. An equal pair resets both to 1. The answer is the largest value either counter ever reaches.
Array [4, 8, 2, 9, 1, 7, 7, 3]. up and down both start at 1 — index 0 alone is a turbulent run of length one.
class Solution:
def maxTurbulenceSize(self, arr: List[int]) -> int:
up = down = best = 1
for i in range(1, len(arr)):
if arr[i] > arr[i - 1]:
up, down = down + 1, 1
elif arr[i] < arr[i - 1]:
down, up = up + 1, 1
else:
up = down = 1
best = max(best, up, down)
return bestclass Solution:
def maxTurbulenceSize(self, arr: List[int]) -> int:
n = len(arr)
best = 1
for i in range(n):
for j in range(i, n):
if self.isTurbulent(arr[i:j + 1]):
best = max(best, j - i + 1)
return best
def isTurbulent(self, sub: List[int]) -> bool:
if len(sub) == 1:
return True
signs = []
for k in range(len(sub) - 1):
if sub[k] == sub[k + 1]:
return False
signs.append(1 if sub[k + 1] > sub[k] else -1)
for k in range(1, len(signs)):
if signs[k] == signs[k - 1]:
return False
return Trueclass Solution {
public int maxTurbulenceSize(int[] arr) {
int up = 1, down = 1, best = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] > arr[i - 1]) {
up = down + 1;
down = 1;
} else if (arr[i] < arr[i - 1]) {
down = up + 1;
up = 1;
} else {
up = 1;
down = 1;
}
best = Math.max(best, Math.max(up, down));
}
return best;
}
}class Solution {
public int maxTurbulenceSize(int[] arr) {
int n = arr.length;
int best = 1;
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
if (isTurbulent(arr, i, j)) {
best = Math.max(best, j - i + 1);
}
}
}
return best;
}
private boolean isTurbulent(int[] arr, int i, int j) {
if (i == j) {
return true;
}
Integer prevSign = null;
for (int k = i; k < j; k++) {
if (arr[k] == arr[k + 1]) {
return false;
}
int sign = arr[k + 1] > arr[k] ? 1 : -1;
if (prevSign != null && sign == prevSign) {
return false;
}
prevSign = sign;
}
return true;
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED