Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit

Updated on 05 June, 2025
Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit header image

Problem Statement

Given an array nums of integers and an integer limit, you are required to determine the length of the longest contiguous subarray where the absolute difference between any two elements within the subarray does not exceed the limit. It is essential that the subarray, whose length you are calculating, is non-empty. The task encapsulates understanding the variability within the subarray that fits under the defined threshold to ensure that it remains the longest while adhering to the condition of the limit on absolute differences between its elements.

Examples

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

Approach and Intuition

Understanding how to find the longest subarray where the absolute difference between any two elements does not exceed a certain limit can be tricky. Here's an intuitive way to approach solving this problem:

  1. Maintaining Range Information with a Deque: By using a double-ended queue (deque), we can efficiently manage the maximum and minimum elements in window slices of the array, which helps in checking the limit condition.

  2. Sliding Window Technique:

    • Traverse through the array using two pointers to mark the boundaries of our current subarray (window); let's call them start and end.
    • Incrementally expand the end pointer to include elements in the subarray and update our deque structure to add elements in order while ensuring we maintain them from largest to smallest.
    • At each step, compare the maximum and minimum of the current subarray to check if they comply with the limit.
    • If the condition violates, move the start pointer to shrink the subarray until it satisfies the condition.
    • Keep track of the size of subarrays which meet the condition and update the maximum size encountered.
  3. Edge Cases Handling:

    • When nums has only one element, the answer will always be 1 because there's no other element to compare to.
    • Consider different edge cases especially when limit is 0, which forces all elements of the valid subarray to be identical. Use this information to optimize the solution.

By applying these strategies, the problem becomes one of optimally managing and updating a window of elements such that at each step, we try to maintain a valid and as large as possible subarray segment that fits within the described limits of maximum absolute difference. The use of data structures like deque ensures that operations to find maximum and minimum, which are integral to our checks against the limit, are efficient.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int maxSubarrayWithLimit(vector<int>& data, int threshold) {
        deque<int> highestValues, lowestValues;
        int start = 0, end;
        int maxLen = 0;

        for (end = 0; end < data.size(); ++end) {
            while (!highestValues.empty() && highestValues.back() < data[end]) {
                highestValues.pop_back();
            }
            highestValues.push_back(data[end]);

            while (!lowestValues.empty() && lowestValues.back() > data[end]) {
                lowestValues.pop_back();
            }
            lowestValues.push_back(data[end]);

            while (highestValues.front() - lowestValues.front() > threshold) {
                if (highestValues.front() == data[start]) {
                    highestValues.pop_front();
                }
                if (lowestValues.front() == data[start]) {
                    lowestValues.pop_front();
                }
                ++start;
            }

            maxLen = max(maxLen, end - start + 1);
        }

        return maxLen;
    }
};

The provided C++ solution aims to calculate the length of the longest subarray where the absolute difference between the maximum and minimum elements is less than or equal to a given threshold. The solution employs the following steps:

  1. Initialize two deques to maintain the highest and lowest values encountered while traversing the array.
  2. Use two pointers, start and end, to represent the current subarray being considered.
  3. Iterate through the array using the end pointer. For each element:
    • Update the highestValues deque by removing elements from the back until the current element is less than or equal to the last element in the deque, and then add the current element to the deque.
    • Similarly, update the lowestValues deque by removing elements from the back until the current element is greater than or equal to the last element in the deque, and then add the current element to the deque.
    • If the difference between the front of the highestValues and lowestValues exceeds the threshold, adjust the start pointer to reduce the subarray size until the condition is met.
  4. Calculate the length of the current subarray and update maxLen if the current subarray is longer.
  5. Return maxLen as the result, which is the maximum length of a subarray that meets the criteria.

This approach efficiently handles the varying conditions of the subarray with the help of two deques, allowing for dynamic adjustment of the subarray boundaries based on the two-pointer technique. The solution guarantees that each element is processed in constant time on average, leading to an overall linear time complexity. This method is effective for handling large datasets and ensures optimal performance.

java
class Solution {

    public int findLongestSubarray(int[] array, int threshold) {
        Deque<Integer> descDeque = new LinkedList<>();
        Deque<Integer> ascDeque = new LinkedList<>();
        int start = 0;
        int longest = 0;

        for (int end = 0; end < array.length; ++end) {
            // Keep descDeque in descending order
            while (!descDeque.isEmpty() && descDeque.peekLast() < array[end]) {
                descDeque.pollLast();
            }
            descDeque.offerLast(array[end]);

            // Keep ascDeque in ascending order
            while (!ascDeque.isEmpty() && ascDeque.peekLast() > array[end]) {
                ascDeque.pollLast();
            }
            ascDeque.offerLast(array[end]);

            // Ensure the window is within the allowed limit
            while (descDeque.peekFirst() - ascDeque.peekFirst() > threshold) {
                if (descDeque.peekFirst() == array[start]) {
                    descDeque.pollFirst();
                }
                if (ascDeque.peekFirst() == array[start]) {
                    ascDeque.pollFirst();
                }
                ++start;
            }

            longest = Math.max(longest, end - start + 1);
        }

        return longest;
    }
}

This Java solution finds the length of the longest continuous subarray where the absolute difference between any two elements is less than or equal to a given threshold. The approach utilizes two deques to maintain a window of values that can expand and contract based on the provided conditions:

  • DescDeque maintains values in descending order.
  • AscDeque maintains values in ascending order.

As you iterate through the array,

  • Add new elements appropriately to both Deques to maintain their order.
  • Check if the difference between the first elements of the two deques exceeds the threshold. If it does, adjust the starting index of the window accordingly.
  • At each step, calculate the length of the current valid subarray, and update the maximum length found.

The algorithm efficiently handles updates to the window size and keeps track of the current and maximum lengths of subarrays that meet the condition using the following approach:

  • Expand the window by adding elements to the back of each deque.
  • Contract the window from the start if the condition is violated.
  • Maintain the maximum length encountered during traversal.

Ultimately, the function returns the size of the longest subarray that satisfies the given conditions. This method ensures that edge cases, like single element arrays or no valid subarray exceeding the threshold, are handled correctly by the robust update mechanism of the deques.

python
class Solution:
    def findLongestSubarray(self, numbers: List[int], threshold: int) -> int:
        ascending = deque()
        descending = deque()
        start = 0
        longest = 0

        for end in range(len(numbers)):
            # Descending deque maintains the largest elements at the front
            while descending and descending[-1] < numbers[end]:
                descending.pop()
            descending.append(numbers[end])

            # Ascending deque maintains the smallest elements at the front
            while ascending and ascending[-1] > numbers[end]:
                ascending.pop()
            ascending.append(numbers[end])

            # Adjust the window size if the difference exceeds the threshold
            while descending[0] - ascending[0] > threshold:
                if descending[0] == numbers[start]:
                    descending.popleft()
                if ascending[0] == numbers[start]:
                    ascending.popleft()
                start += 1

            # Update the longest length found
            longest = max(longest, end - start + 1)

        return longest

To solve the problem of finding the longest continuous subarray where the absolute difference between any two elements is less than or equal to a given limit, this Python solution utilizes the double-ended queue (deque) data structure for efficient element addition and removal at both ends.

  • Initialize two deques, ascending and descending, to keep track of minimum and maximum values in the current window, respectively.
  • Use two pointers, start and end, to represent the current window's bounds.
  • Iterate through the numbers array using the end pointer.
  • For the descending deque, remove elements from the back until the current number is less than or equal to the last element in the deque and then append the current number. This ensures that the highest elements are always at the front.
  • Similarly, for the ascending deque, remove elements from the back until the current number is greater than or equal to the last element and append the current number. This keeps the lowest elements at the front.
  • If the difference between the maximum (front of descending) and the minimum (front of ascending) exceeds the threshold, adjust the start pointer:
    • Remove the start element from the deques if it matches their front element.
    • Increment the start pointer.
  • Continuously update the longest length of the subarray as the difference between end and start plus one.

Once the loop completes, return the value of longest, which contains the size of the longest subarray meeting the condition. This approach effectively maintains the range of values in the current window, allowing for fast updates and checks against the threshold condition.

Comments

No comments yet.