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 index [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 indexes [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++
#include <bits/stdc++.h>
using namespace std;
void longestSubarray( int * A, int N, int X)
{
int maxLen = 0;
int beginning = 0;
map< int , int > window;
int start = 0, end = 0;
for (; end < N; end++) {
window[A[end]]++;
auto minimum = window.begin()->first;
auto maximum = window.rbegin()->first;
if (maximum - minimum <= X) {
if (maxLen < end - start + 1) {
maxLen = end - start + 1;
beginning = start;
}
}
else {
while (start < end) {
window[A[start]]--;
if (window[A[start]] == 0) {
window.erase(window.find(A[start]));
}
start++;
auto minimum = window.begin()->first;
auto maximum = window.rbegin()->first;
if (maximum - minimum <= X)
break ;
}
}
}
for ( int i = beginning; i < beginning + maxLen; i++)
cout << A[i] << " " ;
}
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;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG
{
static void longestSubarray( int A[], int N, int X)
{
int maxLen = 0 ;
int beginning = 0 ;
TreeMap<Integer, Integer> window = new TreeMap<>();
int start = 0 , end = 0 ;
for (; end < N; end++)
{
window.put(A[end],
window.getOrDefault(A[end], 0 ) + 1 );
int minimum = window.firstKey();
int maximum = window.lastKey();
if (maximum - minimum <= X)
{
if (maxLen < end - start + 1 ) {
maxLen = end - start + 1 ;
beginning = start;
}
}
else {
while (start < end)
{
window.put(A[start],
window.get(A[start]) - 1 );
if (window.get(A[start]) == 0 ) {
window.remove(A[start]);
}
start++;
minimum = window.firstKey();
maximum = window.lastKey();
if (maximum - minimum <= X)
break ;
}
}
}
for ( int i = beginning; i < beginning + maxLen; i++)
System.out.print(A[i] + " " );
}
public static void main(String[] args)
{
int arr[] = { 15 , 10 , 1 , 2 , 4 , 7 , 2 }, X = 5 ;
int n = arr.length;
longestSubarray(arr, n, X);
}
}
|
Python3
def longestSubarray(A, N, X):
maxLen = 0
beginning = 0
window = {}
start = 0
for end in range (N):
if A[end] in window:
window[A[end]] + = 1
else :
window[A[end]] = 1
minimum = min ( list (window.keys()))
maximum = max ( list (window.keys()))
if maximum - minimum < = X:
if maxLen < end - start + 1 :
maxLen = end - start + 1
beginning = start
else :
while start < end:
window[A[start]] - = 1
if window[A[start]] = = 0 :
window.pop(A[start])
start + = 1
minimum = min ( list (window.keys()))
maximum = max ( list (window.keys()))
if maximum - minimum < = X:
break
for i in range (beginning, beginning + maxLen):
print (A[i], end = ' ' )
arr = [ 15 , 10 , 1 , 2 , 4 , 7 , 2 ]
X = 5
n = len (arr)
longestSubarray(arr, n, X)
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
static void longestSubarray( int [] A, int N, int X)
{
int maxLen = 0;
int beginning = 0;
Dictionary< int , int > window = new Dictionary< int , int >();
int start = 0, end = 0;
for (; end < N; end++)
{
if (!window.ContainsKey(A[end]))
window[A[end]] = 0;
window[A[end]]++;
int minimum = window.Keys.Min();
int maximum = window.Keys.Max();
if (maximum - minimum <= X)
{
if (maxLen < end - start + 1) {
maxLen = end - start + 1;
beginning = start;
}
}
else {
while (start < end)
{
window[A[start]]--;
if (window[A[start]] == 0) {
window.Remove(A[start]);
}
start++;
minimum =window.Keys.Min();
maximum = window.Keys.Max();
if (maximum - minimum <= X)
break ;
}
}
}
for ( int i = beginning; i < beginning + maxLen; i++)
Console.Write(A[i] + " " );
}
public static void Main( string [] args)
{
int [] arr = { 15, 10, 1, 2, 4, 7, 2 };
int X = 5;
int n = arr.Length;
longestSubarray(arr, n, X);
}
}
|
Javascript
<script>
function longestSubarray(A, N, X){
let maxLen = 0
let beginning = 0
let window = new Map()
let start = 0
for (let end=0;end<N;end++){
if (window.has(A[end]))
window.set(A[end],window.get(A[end]) + 1)
else
window.set(A[end] , 1)
let minimum = Math.min(...window.keys())
let maximum = Math.max(...window.keys())
if (maximum - minimum <= X){
if (maxLen < end - start + 1){
maxLen = end - start + 1
beginning = start
}
}
else {
while (start < end){
window.set(A[start],window.get(A[start]) - 1)
if (window.get(A[start]) == 0)
window. delete (A[start])
start += 1
minimum = Math.min(...window.keys())
maximum = Math.max(...window.keys())
if (maximum - minimum <= X)
break
}
}
}
for (let i=beginning;i<beginning+maxLen;i++){
document.write(A[i], ' ' )
}
}
let arr = [15, 10, 1, 2, 4, 7, 2]
let X = 5
let n = arr.length
longestSubarray(arr, n, X)
</script>
|
Time Complexity: O(N * log(N))