Longest subarray with difference exactly K between any two distinct values

Given an array arr[] of length N and an integer K, the task is to find the longest subarray with difference between any two distict values equal to K. Print the length of the longest subarray obtained. Otherwise, if no such subarray is obtained, print -1.

Examples: 

Input: arr[] = {0, 0, 1, 1, 3, 3, 3}, K = 1 
Output:
Explanation: 
The subarray {0, 0, 1, 1} is the only subarray having difference between any two distinct values equal to K( = 1). Hence, length is equal to 4.

Input: arr[] = {5, 7, 1, 1, 2, 4, 4, 4, 5, 5, 4, 5, 8, 9}, K = 1 
Output:
Explanation: 
Subarrays {1, 1, 2}, {4, 4, 4, 5, 5, 4, 5} and {8, 9} are the only subarray having difference between any two distinct values equal to K( = 1). 
The longest subarray among them is {4, 4, 4, 5, 5, 4, 5}. 
Hence, the length is 7. 

Naive Approach:



Time Complexity: O(N3) 
Auxiliary Space: O(N)

Efficient Approach: 
It can be observed that for any subarray to consist of elements with the difference between any two elements to be exactly K, the subarray must consist of only two distinct values. Hence, the above approach can be further optimized by using set to find longest sub-array having only two distinct values with a difference K. Follow the steps below to solve the problem: 

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to find the
// longest subarray consisting of
// only two values with difference K
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the length
// of the longest sub-array
int longestSubarray(int arr[], int n,
                    int k)
{
    int i, j, Max = 1;
 
    // Initialize set
    set<int> s;
 
    for (i = 0; i < n - 1; i++) {
        // Store 1st element of
        // sub-array into set
        s.insert(arr[i]);
 
        for (j = i + 1; j < n; j++) {
            // Check absolute difference
            // between two elements
 
            if (abs(arr[i] - arr[j]) == 0
                || abs(arr[i] - arr[j]) == k) {
 
                // If the new element is not
                // present in the set
                if (!s.count(arr[j])) {
 
                    // If the set contains
                    // two elements
                    if (s.size() == 2)
                        break;
 
                    // Otherwise
                    else
                        s.insert(arr[j]);
                }
            }
            else
                break;
        }
 
        if (s.size() == 2) {
 
            // Update the maximum
            // length
            Max = max(Max, j - i);
 
            // Remove the set
            // elements
            s.clear();
        }
        else
            s.clear();
    }
 
    return Max;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 0, 2, 2, 5, 5, 5 };
 
    int N = sizeof(arr)
            / sizeof(arr[0]);
    int K = 1;
 
    int length = longestSubarray(
        arr, N, K);
 
    if (length == 1)
        cout << -1;
    else
        cout << length;
 
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to find the
// longest subarray consisting of
// only two values with difference K
import java.util.*;
 
class GFG{
 
// Function to return the length
// of the longest sub-array
static int longestSubarray(int arr[], int n,
                        int k)
{
    int i, j, Max = 1;
 
    // Initialize set
    HashSet<Integer> s = new HashSet<Integer>();
 
    for(i = 0; i < n - 1; i++)
    {
         
        // Store 1st element of
        // sub-array into set
        s.add(arr[i]);
 
        for(j = i + 1; j < n; j++)
        {
             
            // Check absolute difference
            // between two elements
            if (Math.abs(arr[i] - arr[j]) == 0 ||
                Math.abs(arr[i] - arr[j]) == k)
            {
                 
                // If the new element is not
                // present in the set
                if (!s.contains(arr[j]))
                {
                     
                    // If the set contains
                    // two elements
                    if (s.size() == 2)
                        break;
 
                    // Otherwise
                    else
                        s.add(arr[j]);
                }
            }
            else
                break;
        }
        if (s.size() == 2)
        {
             
            // Update the maximum
            // length
            Max = Math.max(Max, j - i);
 
            // Remove the set
            // elements
            s.clear();
        }
        else
            s.clear();
    }
    return Max;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 0, 2, 2, 5, 5, 5 };
 
    int N = arr.length;
    int K = 1;
    int length = longestSubarray(arr, N, K);
 
    if (length == 1)
        System.out.print(-1);
    else
        System.out.print(length);
}
}
 
// This code is contributed by Princi Singh
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to find the 
# longest subarray consisting of 
# only two values  with difference K
 
# Function to return the length 
# of the longest sub-array
def longestSubarray (arr, n, k):
 
    Max = 1
 
    # Initialize set
    s = set()
 
    for i in range(n - 1):
 
        # Store 1st element of
        # sub-array into set
        s.add(arr[i])
 
        for j in range(i + 1, n):
             
            # Check absolute difference
            # between two elements
            if (abs(arr[i] - arr[j]) == 0 or
                abs(arr[i] - arr[j]) == k):
 
                # If the new element is not
                # present in the set
                if (not arr[j] in s):
 
                    # If the set contains
                    # two elements
                    if (len(s) == 2):
                        break
 
                    # Otherwise
                    else:
                        s.add(arr[j])
                         
            else:
                break
 
        if (len(s) == 2):
 
            # Update the maximum length
            Max = max(Max, j - i)
 
            # Remove the set elements
            s.clear()
 
        else:
            s.clear()
 
    return Max
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 0, 2, 2, 5, 5, 5 ]
 
    N = len(arr)
    K = 1
 
    length = longestSubarray(arr, N, K)
 
    if (length == 1):
        print("-1")
    else:
        print(length)
 
# This code is contributed by himanshu77
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to find the
// longest subarray consisting of
// only two values with difference K
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to return the length
// of the longest sub-array
static int longestSubarray(int []arr, int n,
                                      int k)
{
    int i, j, Max = 1;
 
    // Initialize set
    HashSet<int> s = new HashSet<int>();
 
    for(i = 0; i < n - 1; i++)
    {
         
        // Store 1st element of
        // sub-array into set
        s.Add(arr[i]);
 
        for(j = i + 1; j < n; j++)
        {
             
            // Check absolute difference
            // between two elements
            if (Math.Abs(arr[i] - arr[j]) == 0 ||
                Math.Abs(arr[i] - arr[j]) == k)
            {
                 
                // If the new element is not
                // present in the set
                if (!s.Contains(arr[j]))
                {
                     
                    // If the set contains
                    // two elements
                    if (s.Count == 2)
                        break;
 
                    // Otherwise
                    else
                        s.Add(arr[j]);
                }
            }
            else
                break;
        }
        if (s.Count == 2)
        {
             
            // Update the maximum
            // length
            Max = Math.Max(Max, j - i);
 
            // Remove the set
            // elements
            s.Clear();
        }
        else
            s.Clear();
    }
    return Max;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 1, 0, 2, 2, 5, 5, 5 };
 
    int N = arr.Length;
    int K = 1;
    int length = longestSubarray(arr, N, K);
 
    if (length == 1)
        Console.Write(-1);
    else
        Console.Write(length);
}
}
 
// This code is contributed by Princi Singh
chevron_right

Output: 
2

 

Time Complexity: O(N2 * logN) 
Auxiliary Space: O(N) 

 




Recommended Posts:


Check out this Author's contributed articles.

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 : princi singh, himanshu77

Article Tags :