Variable-size windows expand when adding elements is beneficial and shrink when a constraint is violated.
Template for "find longest subarray with condition":
left = 0
for right from 0 to n-1:
// Expand: add arr[right] to window state
while window violates condition:
// Shrink: remove arr[left] from window state
left = left + 1
// Window [left, right] is valid
update answer with (right - left + 1)
core idea: right always moves forward. left only moves forward (never backward). Each element is added once and removed at most once. Total: .