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
.
Example 1:
Input: nums = [8,2,4,7], limit = 4 Output: 2 Explanation: 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 is 2.
Example 2:
Input: nums = [10,1,2,4,7,2], limit = 5 Output: 4 Explanation: The subarray [2,4,7,2] is the longest since the maximum absolute diff is |2-7| = 5 <= 5.
Example 3:
Input: nums = [4,2,2,2,4,4,2,2], limit = 0 Output: 3
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 109
0 <= limit <= 109
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
.
This solution uses an ordered set (like SortedList
in Python or TreeMap
in Java) and a sliding window approach. The ordered set efficiently tracks the minimum and maximum values within the current window.
Algorithm:
sl
and variables ans
(to store the maximum length) and j
(left pointer of the sliding window).nums
array using a pointer i
.nums[i]
to the ordered set sl
.sl
exceeds limit
:
nums[j]
from sl
.j
(move the left boundary of the window).ans
with the maximum of ans
and i - j + 1
(current window size).ans
.Time Complexity: O(n log n) - Due to the ordered set operations (insertion and removal). Space Complexity: O(n) - The ordered set can store up to n elements in the worst case.
This solution uses binary search to find the longest subarray length. For a given length k
, it checks if a subarray of length k
exists that satisfies the condition using two monotonic deques (one for min and one for max).
Algorithm:
check(k)
:
min_q
and max_q
, to track minimum and maximum elements within a window of size k
.nums
using a sliding window of size k
.min_q
and max_q
such that they contain indices of the minimum and maximum elements within the current window.nums[max_q[0]] - nums[min_q[0]]
) is less than or equal to limit
, return True
.False
if no such window is found.len(nums)
). check(k)
determines whether a subarray of length k
exists.l
from the binary search will be the length of the longest subarray.Time Complexity: O(n log n) - Binary search iterates log n times, and check(k)
takes O(n) time.
Space Complexity: O(n) - The deques can store up to n elements each.
This is an optimized solution that uses two deques to track the maximum and minimum values within the sliding window in linear time.
Algorithm:
maxq
and minq
, for storing indices of maximum and minimum elements respectively.l
(left boundary) and r
(right boundary) of the sliding window.nums
using r
:
maxq
is not empty and the element at the back of maxq
is less than nums[r]
, pop from the back of maxq
.minq
is not empty and the element at the back of minq
is greater than nums[r]
, pop from the back of minq
.r
to the back of both maxq
and minq
.nums[maxq[0]]
) and minimum (nums[minq[0]]
) elements exceeds limit
:
l
.maxq
and minq
that are less than l
.n - l
.Time Complexity: O(n) - Each element is processed a constant number of times. Space Complexity: O(n) - The deques can store up to n elements in the worst case.
Code Examples (Python):
Solution 3 (Most efficient):
from collections import deque
class Solution:
def longestSubarray(self, nums: List[int], limit: int) -> int:
maxq = deque()
minq = deque()
l, n = 0, len(nums)
for r, x in enumerate(nums):
while maxq and nums[maxq[-1]] < x:
maxq.pop()
while minq and nums[minq[-1]] > x:
minq.pop()
maxq.append(r)
minq.append(r)
if nums[maxq[0]] - nums[minq[0]] > limit:
l += 1
if maxq[0] < l:
maxq.popleft()
if minq[0] < l:
minq.popleft()
return n - l
The other solutions can be implemented similarly in other languages like Java, C++, and Go using appropriate data structures (e.g., TreeMap
in Java, std::multiset
in C++, container/heap
in Go for Solution 1). Note that Solution 2 requires a custom deque implementation in some languages for optimal performance. Solution 3 provides the best time complexity.