The window is valid exactly when max(window) − min(window) ≤ limit. Rescanning the window for its max and min on every step is O(n·k), so you carry the two extremes instead: a decreasing deque whose front is the window max, and an increasing deque whose front is the window min. Each new value back-pops every index it dominates — those indices are younger-and-worse, so they can never be an extreme again while the newcomer is in the window — and each index leaving on the left front-pops only if it happened to be the extreme. Compare LC 239 in this library: sliding window maximum asks for the max, so one deque is enough; 1438 asks about the spread, so it needs both, and the validity test is just maxDeque.front − minDeque.front read every step.
while loops are amortised O(1). Sub-variant I: the predicate needs an
aggregate the window cannot maintain incrementally, so you maintain the argmax and argmin instead.
One deque answers "what is the max" (LC 239); two answer "how wide is the spread".