Longest subarray in which absolute difference between any two element is not greater than X

Given an integer array arr[] of size N and an integer X, the task is to find the longest sub-array where the absolute difference between any two elements is not greater than X.

Examples:

Input: arr = { 8, 4, 2, 6, 7 }, X = 4
Output: 4 2 6
Explanation:
The sub-array described by indexs [1, 3], i.e, { 4, 2, 6 } contains no such difference of two elements which is greater than 4.

Input: arr = { 15, 10, 1, 2, 4, 7, 2}, X = 5
Output: 2 4 7 2
Explanation:
The sub-array described by indexs [3, 6], i.e, { 2, 4, 7, 2 } contains no such difference of two elements which is greater than 5.

Naive Approach: Simple solution is to consider all subarrays one by one, find the maximum and minimum element of that sub-array and check if their difference is not greater than X. Among all such sub-arrays print the longest sub-array.



Time Complexity: O(N3)

Efficient Approach: The idea is to use the Sliding Window Technique to consider a sub-array and use a Map data structure to find the maximum and minimum element in that sub-array.

  • At first the Start and End of the window points to the 0-th index.
  • At every iteration, the element at End is inserted in the Map if not already present or otherwise its count is incremented.
  • If the difference between the maximum and minimum element is not greater than X, then update the maximum length of the required sub-array and store the beginning of that sub-array in a variable.
  • Otherwise, increment the Start of the window until the difference between the maximum and minimum element is not greater than X.
  • When incrementing the Start, the size of the window decreases, remove the element at the Start from the Map if and only if the count of that element becomes zero.

Finally, print the sub-array with the longest length, and the absolute difference between any two elements is not greater than the X.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the longest sub-array
// where the absolute difference between any
// two elements is not greater than X
  
#include <bits/stdc++.h>
using namespace std;
  
// Function that prints the longest sub-array
// where the absolute difference between any
// two element is not greater than X
void longestSubarray(int* A, int N, int X)
{
    // Initialize a variable to store
    // length of longest sub-array
    int maxLen = 0;
  
    // Initialize a variable to store the
    // beginning of the longest sub-array
    int beginning = 0;
  
    // Initialize a map to store the maximum
    // and the minimum elements for a given window
    map<int, int> window;
  
    // Initialize the window
    int start = 0, end = 0;
  
    // Loop througth the array
    for (; end < N; end++) {
        // Increment the count of that
        // element in the window
        window[A[end]]++;
  
        // Find the maximum and minimum element
        // in the current window
        auto minimum = window.begin()->first;
        auto maximum = window.rbegin()->first;
  
        // If the difference is not
        // greater than X
        if (maximum - minimum <= X) {
            // Update the length of the longest
            // sub-array and store the beginning
            // of the sub-array
            if (maxLen < end - start + 1) {
                maxLen = end - start + 1;
                beginning = start;
            }
        }
        // Decrease the size of the window
        else {
            while (start < end) {
                // Remove the element at start
                window[A[start]]--;
  
                // Remove the element from the window
                // if its count is zero
                if (window[A[start]] == 0) {
  
                    window.erase(window.find(A[start]));
                }
                // Increment the start of the window
                start++;
  
                // Find the maximum and minimum element
                // in the current window
                auto minimum = window.begin()->first;
                auto maximum = window.rbegin()->first;
  
                // Stop decreasing the size of window
                // when difference is not greater
                if (maximum - minimum <= X)
                    break;
            }
        }
    }
  
    // Print the longest sub-array
    for (int i = beginning; i < beginning + maxLen; i++)
        cout << A[i] << " ";
}
  
// Driver Code
int main()
{
    int arr[] = { 15, 10, 1, 2, 4, 7, 2 }, X = 5;
  
    int n = sizeof(arr) / sizeof(arr[0]);
  
    longestSubarray(arr, n, X);
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the longest sub-array
# where the absolute difference between any
# two elements is not greater than X
  
# Function that prints the longest sub-array
# where the absolute difference between any
# two element is not greater than X
def longestSubarray(A, N, X):
      
    # Initialize a variable to store
    # length of longest sub-array
    maxLen = 0
  
    # Initialize a variable to store the
    # beginning of the longest sub-array
    beginning = 0
  
    # Initialize a map to store the maximum
    # and the minimum elements for a given window
    window = {}
  
    # Initialize the window
    start = 0
  
    # Loop througth the array
    for end in range(N):
  
        # Increment the count of that
        # element in the window
        if A[end] in window:
            window[A[end]] += 1
        else:
            window[A[end]] = 1
  
        # Find the maximum and minimum element
        # in the current window
        minimum = min(list(window.keys()))
        maximum = max(list(window.keys()))
  
        # If the difference is not
        # greater than X
        if maximum - minimum <= X:
              
            # Update the length of the longest
            # sub-array and store the beginning
            # of the sub-array
            if maxLen < end - start + 1:
                maxLen = end - start + 1
                beginning = start
  
        # Decrease the size of the window
        else:
            while start < end:
  
                # Remove the element at start
                window[A[start]] -= 1
  
                # Remove the element from the window
                # if its count is zero
                if window[A[start]] == 0:
                    window.pop(A[start])
  
                # Increment the start of the window
                start += 1
  
                # Find the maximum and minimum element
                # in the current window
                minimum = min(list(window.keys()))
                maximum = max(list(window.keys()))
  
                # Stop decreasing the size of window
                # when difference is not greater
                if maximum - minimum <= X:
                    break
                      
    # Print the longest sub-array
    for i in range(beginning, beginning + maxLen):
        print(A[i], end = ' ')
  
# Driver Code
arr = [15, 10, 1, 2, 4, 7, 2]
X = 5
n = len(arr)
longestSubarray(arr, n, X)
  
# This code is contributed by Shivam Singh

chevron_right


Output:

2 4 7 2

Time Complexity: O(N * log(N))

competitive-programming-img




My Personal Notes arrow_drop_up

Recommended Posts:


Coder Machine Learner Social Activist Vocalist

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : SHIVAMSINGH67