Given an array of integers nums and an integer limit, return the size of the longest non-empty subarray such that the absolute difference between any two elements of this subarray is less than or equal to limit.
Input: nums =[8,2,4,7], limit =4Output: 2Explanation: All subarrays are:[8]with maximum absolute diff |8-8|=0<=4.[8,2]with maximum absolute diff |8-2|=6>4.[8,2,4]with maximum absolute diff |8-2|=6>4.[8,2,4,7]with maximum absolute diff |8-2|=6>4.[2]with maximum absolute diff |2-2|=0<=4.[2,4]with maximum absolute diff |2-4|=2<=4.[2,4,7]with maximum absolute diff |2-7|=5>4.[4]with maximum absolute diff |4-4|=0<=4.[4,7]with maximum absolute diff |4-7|=3<=4.[7]with maximum absolute diff |7-7|=0<=4.Therefore, the size of the longest subarray is2.
Example 2:
1
2
3
Input: nums =[10,1,2,4,7,2], limit =5Output: 4Explanation: The subarray [2,4,7,2]is the longest since the maximum absolute diff is|2-7|=5<=5.
Use two pointers (left and right) to represent the current window. The right pointer is used to expand the window, and the left pointer is used to contract it when needed.
Deques for Min and Max:
Maintain two deques:
Monotonically decreasingmaxDeque to store the indices of elements in a way that the values are in decreasing order. This helps in quickly accessing the maximum element.
minDeque to store the indices of elements in a way that the values are in increasing order. This helps in quickly accessing the minimum element.
Adjust the Window:
For every element added to the window (expansion by moving right),
Update the maxDeque - We need to dequeue the “tail” element who is smaller than the nums[right]. Since, those “old small tail” elements will never be the range maximum from now on. After “clean up” the “old small tail” elements, add nums[right] into the deque, and then, the head of deque is the current maximum.
Update minDeque - Clean up “old big tail” elements, add nums[right], the head of deque is the current minimum.
check if the absolute difference between the minimum and maximum elements in the window exceeds the limit.
If it does, slide the left pointer to reduce the window until the condition is satisfied again.
nums[right]is8Update maxDeque:maxDeque becomes [0](index of 8)Update minDeque:minDeque becomes [0](index of 8)Update Window:No need to move left, the window size is now 1(right - left +1)ans =1
nums[right]is2Update maxDeque:Nothing is removed from maxDeque
maxDeque becomes [0,1](index of 8)Update minDeque:Remove 0, since 8>2minDeque becomes [1](index of 2)Update Window:max - min =8-2=6> limit
Hence, move left. left =1We remove all indices less than left from the maxDeque and minDeque as they are out window
maxDeque =[1]minDeque =[1]ans = right - left +1=1
nums[right]is4Update maxDeque:Remove 1, since 4>2maxDeque becomes [2](index of 4)Update minDeque:Nothing is removed from minDeque
minDeque becomes [1,2]Update Window:max - min =4-2=2< limit
No need to move left
ans = right - left +1=2-1+1=2
nums[right]is7Update maxDeque:Remove 2, since 7>4maxDeque becomes [3](index of 7)Update minDeque:Nothing is removed from minDeque
minDeque becomes [1,2,3]Update Window:max - min =7-2=5> limit
We move left, left +=1=2We remove all indices less than left from the maxDeque and minDeque as they are out window
maxDeque =[3]minDeque =[2,3]Check max - min =7-4=3< limit
No need to move left
ans = right - left +1=3-2+1=2
publicclassSolution {
publicintlongestSubarray(int[] nums, int limit) {
int n = nums.length;
if (n == 0) {
return 0;
}
// Deques to keep track of minimum and maximum elements in the window Deque<Integer> maxDeque =new ArrayDeque<>();
Deque<Integer> minDeque =new ArrayDeque<>();
int left = 0;
int ans = 0;
for (int right = 0; right < n; right++) {
while (!maxDeque.isEmpty() && nums[maxDeque.peekLast()]<= nums[right]) {
maxDeque.pollLast();
}
maxDeque.offerLast(right);
while (!minDeque.isEmpty() && nums[minDeque.peekLast()]>= nums[right]) {
minDeque.pollLast();
}
minDeque.offerLast(right);
// Check the conditionwhile (!maxDeque.isEmpty() &&!minDeque.isEmpty() && nums[maxDeque.peekFirst()]- nums[minDeque.peekFirst()]> limit) {
left++;
// Remove the elements which are out of this new windowif (maxDeque.peekFirst()<left) {
maxDeque.pollFirst();
}
if (minDeque.peekFirst()<left) {
minDeque.pollFirst();
}
}
ans = Math.max(ans, right - left + 1);
}
return ans;
}
}