Open In App

Longest subarray with difference exactly K between any two distinct values

Last Updated : 03 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of length N and an integer K, the task is to find the longest subarray with difference between any two distinct 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:

  • A simple solution is to consider all subarrays one by one, and find subarrays which contains only two distinct values and the difference between those two values is K. Keep updating the maximum length of subarray obtained.
  • Finally print the maximum length obtained.

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: 

  • Start the first subarray from starting index of the array.
  • Insert that element into the set. Proceed to the next element and check if this element is the same as the previous or has an absolute difference of K.
  • If so, insert that element into the set and continue increasing the length of the subarray. Once, a third distinct element is found, compare the length of the current subarray with the maximum length of the subarray and update accordingly.
  • Update the new element obtained into the set and proceed to repeat the above steps.
  • Once, the entire array is traversed, print the maximum length obtained.

Below is the implementation of the above approach:

C++




// 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;
}


Java




// 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


Python3




# 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


C#




// 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


Javascript




<script>
    // Javascript implementation to find the
    // longest subarray consisting of
    // only two values with difference K
     
    // Function to return the length
    // of the longest sub-array
    function longestSubarray(arr, n, k)
    {
        let i, j, Max = 1;
 
        // Initialize set
        let s = new Set();
 
        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.has(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;
    }
     
    let arr = [ 1, 0, 2, 2, 5, 5, 5 ];
  
    let N = arr.length;
    let K = 1;
  
    let length = longestSubarray(arr, N, K);
  
    if (length == 1)
        document.write(-1);
    else
        document.write(length);
 
// This code is contributed by decode2207.
</script>


Output: 

2

 

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

Using Sliding Window

Problem statement(simplification)

Here we want to figure the longest Subarray of max size with this these conditions

  1. i.the diff between all elements will equal ==  K Or 0.
  2. ii. the subarray only consists of only two distinct elements.

C++




#include <bits/stdc++.h>
using namespace std;
 
int kdistinct(vector<int> arr, int k)
{
    int end = 1, st = 0, mx = 1;
    map<int, int> mp;
 
    mp[arr[st]]++;
    while (end < arr.size()) {
        // here we are trying to check  the i. Condition
        if (abs(arr[end] - arr[end - 1]) == 0|| abs(arr[end] - arr[end - 1]) == k)
                mp[arr[end]]++;
        else {
            // if the i.condition is not satisfy it mean
            // current pos(starting  Subarray) will not be
            // candidate for max len . skip it .
            mp.clear();
            mp[arr[end]]++;
            st = end;
        }
        if (mp.size() == 2)
            mx = max(mx, end - st + 1);
        end++;
    }
    return mx;
}
 
int main()
{
    vector<int> arr{ 1, 1, 1, 3, 3, 2, 2 };
    int k = 1;
    cout << kdistinct(arr, k);
}


Java




import java.util.*;
 
class GFG {
  static int kdistinct(List<Integer> arr, int k)
  {
    int end = 1, st = 0, mx = 1;
    Map<Integer, Integer> mp = new HashMap<>();
    if (!mp.containsKey(arr.get(st)))
      mp.put(arr.get(st), 0);
    mp.put(arr.get(st), mp.get(arr.get(st)) + 1);
    while (end < arr.size()) {
      // here we are trying to check  the i. Condition
      if (Math.abs(arr.get(end) - arr.get(end - 1))
          == 0
          || Math.abs(arr.get(end) - arr.get(end - 1))
          == k) {
        if (!mp.containsKey(arr.get(end)))
          mp.put(arr.get(end), 0);
        mp.put(arr.get(end),
               mp.get(arr.get(end)) + 1);
      }
      else {
        // if the i.condition is not satisfy it mean
        // current pos(starting  Subarray) will not
        // be candidate for max len . skip it .
        mp.clear();
        mp.put(arr.get(end), 1);
        st = end;
      }
      if (mp.size() == 2)
        mx = Math.max(mx, end - st + 1);
      end++;
    }
    return mx;
  }
 
  public static void main(String[] args)
  {
    List<Integer> arr = new ArrayList<>(
      Arrays.asList(1, 1, 1, 3, 3, 2, 2));
    int k = 1;
    System.out.println(kdistinct(arr, k));
  }
}
 
// This code is contributed by phasing17.


Python3




from collections import defaultdict
 
def kdistinct(arr, k):
    end = 1
    st = 0
    mx = 1;
    mp = defaultdict(lambda : 0);
 
    mp[arr[st]]+= 1;
    while (end < len(arr)):
       
        # here we are trying to check  the i. Condition
        if (abs(arr[end] - arr[end - 1]) == 0 or abs(arr[end] - arr[end - 1]) == k):
                mp[arr[end]] += 1;
        else :
           
            # if the i.condition is not satisfy it mean
            # current pos(starting  Subarray) will not be
            # candidate for max len . skip it .
            mp= defaultdict(lambda : 0);
            mp[arr[end]]+= 1;
            st = end;
         
        if (len(mp) == 2):
            mx = max(mx, end - st + 1);
        end+= 1;
     
    return mx;
 
 
arr = [1, 1, 1, 3, 3, 2, 2];
k = 1;
print(kdistinct(arr, k));
 
# This code is contributed by phasing17.


C#




using System;
using System.Linq;
using System.Collections.Generic;
 
class GFG
{
  static int kdistinct(List<int> arr, int k)
  {
    int end = 1, st = 0, mx = 1;
    Dictionary<int, int> mp = new Dictionary<int, int>();
 
    if (!mp.ContainsKey(arr[st]))
      mp[arr[st]] = 0;
    mp[arr[st]]++;
    while (end < arr.Count) {
      // here we are trying to check  the i. Condition
      if (Math.Abs(arr[end] - arr[end - 1]) == 0|| Math.Abs(arr[end] - arr[end - 1]) == k)
      {
        if (!mp.ContainsKey(arr[end]))
          mp[arr[end]] = 0;
        mp[arr[end]]++;
      }
      else {
        // if the i.condition is not satisfy it mean
        // current pos(starting  Subarray) will not be
        // candidate for max len . skip it .
        mp.Clear();
        mp[arr[end]] = 1;
        st = end;
      }
      if (mp.Count == 2)
        mx = Math.Max(mx, end - st + 1);
      end++;
    }
    return mx;
  }
 
  public static void Main(string[] args)
  {
    List<int> arr = new List<int>{ 1, 1, 1, 3, 3, 2, 2 };
    int k = 1;
    Console.Write(kdistinct(arr, k));
  }
}
 
// This code is contributed by phasing17.


Javascript




function kdistinct(arr, k)
{
    let end = 1, st = 0, mx = 1;
    let mp = {};
     
    if (!mp.hasOwnProperty(arr[st]))
        mp[arr[st]] = 0;
    mp[arr[st]]++;
    while (end < arr.length) {
         
        // here we are trying to check  the i. Condition
        if (Math.abs(arr[end] - arr[end - 1]) == 0 || Math.abs(arr[end] - arr[end - 1]) == k)
        {
            if (!mp.hasOwnProperty(arr[end]))
                mp[arr[end]] = 0;
            mp[arr[end]]++;
        }
        else {
            // if the i.condition is not satisfy it mean
            // current pos(starting  Subarray) will not be
            // candidate for max len . skip it .
            mp = {}
            mp[arr[end]] = 1;
            st = end;
        }
        mx = Math.max(mx, end - st + 1);
        end++;
    }
    return mx;
}
 
let  arr = [ 1, 1, 1, 3, 3, 2, 2 ];
let k = 1;
console.log(kdistinct(arr, k))
 
// This code is contributed by phasing17.


Output

4

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads