Given an array arr[] of N integers and an integer K, our task is to find the length of the longest subarray such that for all possible pairs in the subarray absolute difference between elements is less than or equal to K.
Examples:
Input: arr[] = {2, 4, 5, 5, 5, 3, 1}, K = 0
Output: 3
Explanation:
The possible subarray with difference in elements as 0 is {5, 5, 5} whose length is 3. Hence the output is 3.
Input: arr[] = {1, 2, 3, 6, 7}, K = 2
Output: 3
Explanation:
The possible subarray with difference in elements at most 2 is {1, 2, 3} whose length is 3. Hence the output is 3.
Naive Approach:
To solve the problem mentioned above the naive method is to use The Brute Force approach that is to generate all the possible subarray of the given array and check if the difference between the maximum and minimum element of the subarray is at most K or not. If it is, then update the length of the current subarray with the maximum length. Print the maximum length of the subarray after all the operations.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int computeLongestSubarray( int arr[], int k, int n)
{
int maxLength = 1;
for ( int i = 0; i < n; i++)
{
int minOfSub = arr[i];
int maxOfSub = arr[i];
for ( int j = i + 1; j < n; j++)
{
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
if ((maxOfSub - minOfSub) <= k)
{
int currLength = j - i + 1;
if (maxLength < currLength)
maxLength = currLength;
}
}
}
return maxLength;
}
int main()
{
int arr[] = { 1, 2, 3, 6, 7 };
int k = 2;
int n = sizeof (arr) / sizeof (arr[0]);
int maxLength = computeLongestSubarray(arr, k, n);
cout << (maxLength);
}
|
Java
class GFG {
public static int computeLongestSubarray( int arr[],
int k)
{
int maxLength = 1 ;
for ( int i = 0 ; i < arr.length; i++) {
int minOfSub = arr[i];
int maxOfSub = arr[i];
for ( int j = i + 1 ; j < arr.length; j++) {
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
if ((maxOfSub - minOfSub) <= k) {
int currLength = j - i + 1 ;
if (maxLength < currLength)
maxLength = currLength;
}
}
}
return maxLength;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 6 , 7 };
int k = 2 ;
int maxLength = computeLongestSubarray(arr, k);
System.out.println(maxLength);
}
}
|
Python3
def computeLongestSubarray (arr, k, n):
maxLength = 1
for i in range (n):
minOfSub = arr[i]
maxOfSub = arr[i]
for j in range (i + 1 , n):
if (arr[j] > maxOfSub):
maxOfSub = arr[j]
if (arr[j] < minOfSub):
minOfSub = arr[j]
if ((maxOfSub - minOfSub) < = k):
currLength = j - i + 1
if (maxLength < currLength):
maxLength = currLength
return maxLength
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 6 , 7 ]
k = 2
n = len (arr)
maxLength = computeLongestSubarray(arr, k, n)
print (maxLength)
|
C#
using System;
class GFG
{
public static int computelongestSubarray( int []arr,
int k)
{
int maxLength = 1;
for ( int i = 0; i < arr.Length; i++)
{
int minOfSub = arr[i];
int maxOfSub = arr[i];
for ( int j = i + 1; j < arr.Length; j++)
{
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
if ((maxOfSub - minOfSub) <= k)
{
int currLength = j - i + 1;
if (maxLength < currLength)
maxLength = currLength;
}
}
}
return maxLength;
}
public static void Main(String[] args)
{
int []arr = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computelongestSubarray(arr, k);
Console.WriteLine(maxLength);
}
}
|
Javascript
<script>
function computeLongestSubarray(arr,k)
{
let maxLength = 1;
for (let i = 0; i < arr.length; i++) {
let minOfSub = arr[i];
let maxOfSub = arr[i];
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] > maxOfSub)
maxOfSub = arr[j];
if (arr[j] < minOfSub)
minOfSub = arr[j];
if ((maxOfSub - minOfSub) <= k) {
let currLength = j - i + 1;
if (maxLength < currLength)
maxLength = currLength;
}
}
}
return maxLength;
}
let arr=[1, 2, 3, 6, 7];
let k = 2;
let maxLength = computeLongestSubarray(arr, k);
document.write(maxLength);
</script>
|
Time Complexity: O(n2)
Auxiliary Space: O(n)
Efficient Approach:
To optimize the above approach the idea is to use Heap Data Structure. Initialize a minHeap that will store the indices of the current subarray such that the elements are in ascending order, where the smallest appears at the top and a maxHeap that will store the indices of the current subarray such that the elements are in descending order, where the largest element appears at the top. Then iterate over the entire array and for each iteration check if:
- All the subarray elements satisfy the condition of maxOfSub-minOfSub <= k, then we compare maxLength so far to the length of current subarray and update maxLength to maximum of either maxLength or current subarray length.
- If the condition is not satisfied then increase the beginning pointer for subarray by 1 and remove all indices from minHeap and maxHeap which are not included in the new subarray.
- After each iteration, we increase our subarray length by incrementing the end pointer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int computeLongestSubarray(vector< int > arr, int k)
{
int maxLength = 0;
deque< int > maxHeap;
deque< int > minHeap;
int beg = 0;
int end = 0;
while (end < arr.size()) {
int currEl = arr[end];
while (!maxHeap.empty()
&& arr[maxHeap.back()] <= currEl)
maxHeap.pop_back();
maxHeap.push_back(end);
while (!minHeap.empty()
&& arr[minHeap.back()] >= currEl)
minHeap.pop_back();
minHeap.push_back(end);
int maxOfSub = arr[maxHeap.front()];
int minOfSub = arr[minHeap.front()];
if (maxOfSub - minOfSub <= k) {
int currLength = end - beg + 1;
if (maxLength < currLength)
maxLength = currLength;
}
else {
beg += 1;
while (!minHeap.empty()
&& minHeap.front() < beg)
minHeap.pop_front();
while (!maxHeap.empty()
&& maxHeap.front() < beg)
maxHeap.pop_front();
}
end += 1;
}
return maxLength;
}
int main()
{
vector< int > arr = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computeLongestSubarray(arr, k);
cout << maxLength;
return 0;
}
|
Java
import java.util.*;
class GFG {
public static int computeLongestSubarray( int arr[],
int k)
{
int maxLength = 0 ;
Deque<Integer> maxHeap = new LinkedList<>();
Deque<Integer> minHeap = new LinkedList<>();
int beg = 0 , end = 0 ;
while (end < arr.length) {
int currEl = arr[end];
while (maxHeap.size() > 0 &&
arr[maxHeap.peekLast()] <= currEl)
maxHeap.removeLast();
maxHeap.addLast(end);
while (minHeap.size() > 0 &&
arr[minHeap.peekLast()] >= currEl)
minHeap.removeLast();
minHeap.addLast(end);
int maxOfSub = arr[maxHeap.peekFirst()];
int minOfSub = arr[minHeap.peekFirst()];
if (maxOfSub - minOfSub <= k) {
int currLength = end - beg + 1 ;
if (maxLength < currLength)
maxLength = currLength;
}
else {
beg++;
while (minHeap.size() > 0 &&
minHeap.peekFirst() < beg)
minHeap.removeFirst();
while (maxHeap.size() > 0 &&
maxHeap.peekFirst() < beg)
maxHeap.removeFirst();
}
end++;
}
return maxLength;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 6 , 7 };
int k = 2 ;
int maxLength = computeLongestSubarray(arr, k);
System.out.println(maxLength);
}
}
|
Python3
from collections import deque
def computeLongestSubarray(arr, k):
maxLength = 0
maxHeap = []
minHeap = []
beg = 0
end = 0
while (end < len (arr)):
currEl = arr[end]
while ( len (maxHeap) > 0 and arr[maxHeap[ - 1 ]] < = currEl):
del maxHeap[ - 1 ]
maxHeap.append(end)
while ( len (minHeap) > 0 and arr[minHeap[ - 1 ]] > = currEl):
del minHeap[ - 1 ]
minHeap.append(end)
maxOfSub = arr[maxHeap[ 0 ]]
minOfSub = arr[minHeap[ 0 ]]
if (maxOfSub - minOfSub < = k):
currLength = end - beg + 1
if (maxLength < currLength):
maxLength = currLength
else :
beg + = 1
while ( len (minHeap) > 0 and minHeap[ 0 ] < beg):
del minHeap[ 0 ]
while ( len (maxHeap) > 0 and maxHeap[ 0 ] < beg):
del maxHeap[ 0 ]
end + = 1
return maxLength
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 6 , 7 ]
k = 2
maxLength = computeLongestSubarray(arr, k)
print (maxLength)
|
C#
using System;
class GFG {
public static int computeLongestSubarray( int [] arr,
int k)
{
int maxLength = 0;
int maxOfSub = 0;
int minOfSub = 0;
maxOfSub = arr[0];
minOfSub = arr[0];
int end = 0;
int beg = 0;
while (end < arr.Length) {
int currEl = arr[end];
if (maxOfSub < currEl) {
maxOfSub = currEl;
}
if (minOfSub > currEl) {
minOfSub = currEl;
}
if (maxOfSub - minOfSub <= k) {
int currLength = end - beg + 1;
if (maxLength < currLength)
maxLength = currLength;
}
else {
beg += 1;
if (maxOfSub < beg)
maxOfSub = beg;
if (minOfSub < beg)
minOfSub = beg;
}
end += 1;
}
return maxLength;
}
public static void Main()
{
int [] arr = { 1, 2, 3, 6, 7 };
int k = 2;
int maxLength = computeLongestSubarray(arr, k);
Console.WriteLine(maxLength);
}
}
|
Javascript
<script>
function computeLongestSubarray(arr,k)
{
let maxLength = 0;
let maxHeap = [];
let minHeap = [];
let beg = 0, end = 0;
while (end < arr.length) {
let currEl = arr[end];
while (maxHeap.length > 0 &&
arr[maxHeap[maxHeap.length-1]] <= currEl)
maxHeap.pop();
maxHeap.push(end);
while (minHeap.length > 0 &&
arr[minHeap[minHeap.length-1]] >= currEl)
minHeap.pop();
minHeap.push(end);
let maxOfSub = arr[maxHeap[0]];
let minOfSub = arr[minHeap[0]];
if (maxOfSub - minOfSub <= k) {
let currLength = end - beg + 1;
if (maxLength < currLength)
maxLength = currLength;
}
else {
beg++;
while (minHeap.length > 0 &&
minHeap[0] < beg)
minHeap.shift();
while (maxHeap.length > 0 &&
maxHeap[0] < beg)
maxHeap.shift();
}
end++;
}
return maxLength;
}
let arr=[ 1, 2, 3, 6, 7 ];
let k = 2;
let maxLength = computeLongestSubarray(arr, k);
document.write(maxLength);
</script>
|
Time Complexity: O(n) because every element of the array is added and removed from the heaps only once.
Auxiliary Space: O(n)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
25 Apr, 2023
Like Article
Save Article