0% completed
Given an integer array nums
and an integer limit
, return the maximum length of a continuous subarray such that the absolute difference between any two elements in this subarray is less than or equal to limit
. The subarray must be non-empty.
Example 1:
[6, 7, 9]
or [7, 9, 10]
array. The absolute difference between any two elements in these subarrays is at most 3.Example 2:
Example 3:
[1, 5]
, [5, 9]
, [9, 13]
or [13, 14]
array. The absolute difference between any two elements in these subarrays is at most 4.Constraints:
To solve this problem, we employ the Monotonic Queue technique to maintain two deques: one for tracking the maximum values and one for tracking the minimum values within the current window (subarray). The idea is to expand the window by moving the end
pointer while checking if the difference between the maximum and minimum elements within this window exceeds the given limit
. If it does, we shrink the window by moving the start
pointer until the difference is within the limit
. The length of the window is tracked to determine the maximum length of any valid subarray.
This approach works because the deques allow us to efficiently maintain and update the maximum and minimum values in the window, which enables us to check the conditions and adjust the window size in an optimal manner.
Initialize Data Structures:
maxDeque
for storing indices of elements in decreasing order (to track the maximum values) and minDeque
for storing indices in increasing order (to track the minimum values).start
and maxLength
, to 0
. start
will represent the beginning of the current subarray, and maxLength
will store the maximum length of the valid subarray found.Iterate Through the Array:
end
iterating from 0
to nums.length - 1
. end
represents the end of the current subarray.Update maxDeque
:
maxDeque
is not empty and the value at nums[end]
is greater than or equal to the value at nums[maxDeque.peekLast()]
, remove the last element from maxDeque
.maxDeque
.end
to maxDeque
.Update minDeque
:
minDeque
is not empty and the value at nums[end]
is less than or equal to the value at nums[minDeque.peekLast()]
, remove the last element from minDeque
.minDeque
.end
to minDeque
.Check the Condition:
nums[maxDeque.peekFirst()]
and nums[minDeque.peekFirst()]
is greater than limit
, perform the following steps:
start
pointer by 1 to shrink the window from the left.maxDeque.peekFirst()
is less than start
, remove the first element from maxDeque
.
Reason: We are no longer considering elements before the start
index.minDeque.peekFirst()
is less than start
, remove the first element from minDeque
.
Reason: We are no longer considering elements before the start
index.Update Maximum Length:
end - start + 1
.maxLength
to be the maximum of its current value and the current window length.Return Result:
maxLength
, which contains the length of the longest subarray satisfying the condition.Let's walk through the algorithm with the input nums = [1, 3, 6, 7, 9, 10]
and limit = 3
.
Initial State:
maxDeque = []
, minDeque = []
, start = 0
, maxLength = 0
Iteration 1 (end = 0):
nums[0] = 1
maxDeque
: maxDeque = [0]
(1 is the only element, so it remains)minDeque
: minDeque = [0]
(1 is the only element, so it remains)nums[0] - nums[0] = 0
(within the limit)maxLength
: maxLength = max(0, 0 - 0 + 1) = 1
Iteration 2 (end = 1):
nums[1] = 3
maxDeque
: maxDeque = [1]
(3 is greater than 1, so remove index 0)minDeque
: minDeque = [0, 1]
(3 is greater than 1, so add index 1)nums[1] - nums[0] = 3 - 1 = 2
(within the limit)maxLength
: maxLength = max(1, 1 - 0 + 1) = 2
Iteration 3 (end = 2):
nums[2] = 6
maxDeque
: maxDeque = [2]
(6 is greater than 3, so remove index 1)minDeque
: minDeque = [0, 1, 2]
(6 is greater than 3, so add index 2)nums[2] - nums[0] = 6 - 1 = 5
(exceeds the limit)start
: Move start
to 1
(increment by 1)0
from minDeque
since it is out of the window (minDeque = [1, 2]
)maxLength
: maxLength = max(2, 2 - 1 + 1) = 2
Iteration 4 (end = 3):
nums[3] = 7
maxDeque
: maxDeque = [3]
(7 is greater than 6, so remove index 2)minDeque
: minDeque = [1, 2, 3]
(7 is greater than 6, so add index 3)nums[3] - nums[1] = 7 - 3 = 4
(exceeds the limit)start
: Move start
to 2
(increment by 1)1
from minDeque
since it is out of the window (minDeque = [2, 3]
)maxLength
: maxLength = max(2, 3 - 2 + 1) = 2
Iteration 5 (end = 4):
nums[4] = 9
maxDeque
: maxDeque = [4]
(9 is greater than 7, so remove index 3)minDeque
: minDeque = [2, 3, 4]
(9 is greater than 7, so add index 4)nums[4] - nums[2] = 9 - 6 = 3
(within the limit)maxLength
: maxLength = max(2, 4 - 2 + 1) = 3
Iteration 6 (end = 5):
nums[5] = 10
maxDeque
: maxDeque = [5]
(10 is greater than 9, so remove index 4)minDeque
: minDeque = [2, 3, 4, 5]
(10 is greater than 9, so add index 5)nums[5] - nums[2] = 10 - 6 = 4
(exceeds the limit)start
: Move start
to 3
(increment by 1)2
from minDeque
since it is out of the window (minDeque = [3, 4, 5]
)maxLength
: maxLength = max(3, 5 - 3 + 1) = 3
Final Result:
maxLength = 3
, which is the length of the longest subarray where the absolute difference between the maximum and minimum elements is within the given limit.end
pointer, and for each end
, it may move the start
pointer.maxDeque
and minDeque
at most once, leading to a time complexity of O(n), where n is the number of elements in the array.So, the overall time complexity of the algorithm is O(n).
maxDeque
and minDeque
). In the worst case, both deques may store all the elements of the array if the window size covers the entire array.