We need to find the longest contiguous subarray where the difference between the maximum and minimum elements is at most limit. The condition "the absolute difference between any two elements <= limit" is equivalent to max(subarray) - min(subarray) <= limit. If the overall spread fits within the limit, every pair of elements satisfies the condition, because the largest pairwise difference in any set is between its extremes.
So the problem reduces to finding the longest window [left, right] where max(window) - min(window) <= limit. The work is in tracking the current min and max efficiently as the window slides.
1 <= nums.length <= 10^5: with n up to 100,000, an O(n^2) scan can reach 10^10 operations in the worst case (for example, all elements equal), so we want O(n log n) or better.1 <= nums[i] <= 10^9: values are large, but we only compare differences, so the magnitudes do not affect the algorithm. The values fit in a 32-bit integer, and the largest spread (about 10^9) also fits, so no overflow concern.0 <= limit <= 10^9: the limit can be 0 (only runs of identical elements qualify) or large enough that the whole array is one valid window.Examine every subarray and check whether its spread fits within the limit. For each starting index i, extend the subarray one element at a time while maintaining a running min and max. Once the spread exceeds the limit, stop extending from this start: adding more elements can only widen the spread or leave it unchanged, never shrink it, so no longer subarray starting at i can become valid again.
Track the longest valid subarray seen so far.
maxLen = 1 (every single element is a valid subarray).i from 0 to n-1:currentMin = nums[i] and currentMax = nums[i].j from i+1 to n-1:currentMin and currentMax with nums[j].currentMax - currentMin > limit, break.maxLen = max(maxLen, j - i + 1).maxLen.This discards all the min and max information each time the start advances. A sliding window that moves forward only, without resetting, avoids that wasted work.
Instead of restarting for each starting index, use a sliding window [left, right] that advances both ends in one direction. As right moves forward, add the new element. When the window becomes invalid (spread > limit), shrink from the left until it is valid again.
Removing an element from the left raises a problem: if that element was the current min or max, a single tracking variable cannot tell us the next min or max without rescanning the window. An ordered map solves this. A TreeMap (Java), SortedList (Python), map (C++), or BTreeMap (Rust) keeps the window's elements in sorted order with O(log n) insertion and deletion. The first key is the min, the last key is the max.
The shrinking step never discards a valid answer. For a fixed right, the spread is non-decreasing as left moves left (a wider window contains every element of the narrower one, so its max is at least as large and its min at least as small). So for each right there is a single smallest left at which the window is valid, and every window ending at right that starts before it is invalid. Advancing left only until the window becomes valid lands on exactly that boundary, so no valid window ending at right is skipped.
left = 0, maxLen = 0, and a sorted frequency map.right from 0 to n-1:nums[right] to the frequency map.nums[left]. Remove the key if frequency hits 0.left.maxLen = max(maxLen, right - left + 1).maxLen.TreeMap, Python SortedList, C++ map, C# SortedDictionary, Rust BTreeMap). Each element is inserted and removed at most once, and each operation costs O(log n). The Go, JavaScript, and TypeScript versions shown lack a standard ordered map, so they recover the min and max by scanning the window's distinct values. Because limit is unbounded, a window can hold O(n) distinct values, making those three O(n^2) in the worst case. Approach 3 reaches O(n) in every language.The ordered map maintains a full sort, but the algorithm only ever reads the max and min. Two monotonic deques track exactly those two extremes in amortized O(1), dropping the log factor and the sorted-container overhead.
The algorithm only reads the max and min of the current window, so we maintain those two values with monotonic deques of indices. A decreasing deque tracks the maximum: its front holds the index of the largest element in the window. An increasing deque tracks the minimum: its front holds the index of the smallest.
When a new element arrives at index right, the max deque pops from the back every index whose value is less than or equal to nums[right]. Those elements are both older and no larger than nums[right], so while nums[right] stays in the window they can never be the maximum, and they leave the window before it does. After popping, push right. The min deque is symmetric, popping back values greater than or equal to nums[right]. When the window shrinks, a front index that has fallen below left is popped, since it now points outside the window.
Each index enters and leaves each deque at most once, so the deque work is amortized O(1) per element and O(n) total.
left = 0, maxLen = 0, and two deques: maxDeque (decreasing values) and minDeque (increasing values).right from 0 to n-1:nums[right], then push right.nums[right], then push right.nums[maxDeque.front] - nums[minDeque.front] > limit:left.maxDeque.front < left, pop the front.minDeque.front < left, pop the front.maxLen = max(maxLen, right - left + 1).maxLen.