Open In App

Longest Subsequence with Difference k

Last Updated : 15 Nov, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] and an integer k, find the longest subsequence of the array such that the difference between the maximum and minimum elements in the subsequence is exactly k.

Examples:

Input: arr[] = [2, 3, 6, 5, 3], k = 3
Output: 4
Explanation: The longest subsequence where the difference between the maximum and minimum elements is 3 is [2, 3, 5, 3].

Input: arr[] = [4, 3, 3, 4], k = 4
Output: 0
Explanation: No subsequence exists where the difference between the maximum and minimum elements is 4.

[Naive Approach] Generating All SubSequences - O(2n) Time and O(1) Space

We can generate all subsequences of the array and for each one, calculate the maximum and minimum elements. If the difference between the maximum and minimum equals k, we consider the length of that subsequence for the longest valid answer.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//Driver Code Ends

int longestsub(vector<int> &arr, int k) {
    int n = arr.size();
    int res = 0;

    // There are 2^n possible subsequences
    for (int mask = 1; mask < (1 << n); mask++) {
        vector<int> sub;

        // Build subsequence for current mask
        for (int i = 0; i < n; i++) {
            if (mask & (1 << i)) sub.push_back(arr[i]);
        }

        // Find minimum and maximum of this subsequence
        int mn = *min_element(sub.begin(), sub.end());
        int mx = *max_element(sub.begin(), sub.end());

        // Check if the difference equals k
        if (mx - mn == k) res = max(res, (int)sub.size());
    }

    return res;
}

//Driver Code Starts

int main() {
    vector<int> arr = {2, 3, 6, 5, 3};
    int k = 3;

    cout << longestsub(arr, k) << endl;
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;

class GFG {

//Driver Code Ends

    static int longestsub(int[] arr, int k) {
        int n = arr.length;
        int res = 0;

        // There are 2^n possible subsequences
        for (int mask = 1; mask < (1 << n); mask++) {
            List<Integer> sub = new ArrayList<>();

            // Build subsequence for current mask
            for (int i = 0; i < n; i++) {
                if ((mask & (1 << i)) != 0) sub.add(arr[i]);
            }

            // Find minimum and maximum
            int mn = Collections.min(sub);
            int mx = Collections.max(sub);

            // Check if difference equals k
            if (mx - mn == k) res = Math.max(res, sub.size());
        }

        return res;
    }

//Driver Code Starts

    public static void main(String[] args) {
        int[] arr = {2, 3, 6, 5, 3};
        int k = 3;
        System.out.println(longestsub(arr, k));
    }
}

//Driver Code Ends
Python
#Driver Code Starts
from itertools import combinations

#Driver Code Ends

def longestsub(arr, k):
    n = len(arr)
    res = 0

    # Generate all subsequences
    for r in range(1, n + 1):
        for sub in combinations(arr, r):
            mn = min(sub)
            mx = max(sub)
            if mx - mn == k:
                res = max(res, len(sub))

    return res

#Driver Code Starts

if __name__ == '__main__':
    arr = [2, 3, 6, 5, 3]
    k = 3
    print(longestsub(arr, k))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
using System.Linq;

class GFG {

//Driver Code Ends

    static int longestsub(int[] arr, int k) {
        int n = arr.Length;
        int res = 0;

        // There are 2^n possible subsequences
        for (int mask = 1; mask < (1 << n); mask++) {
            List<int> sub = new List<int>();

            // Build subsequence for current mask
            for (int i = 0; i < n; i++) {
                if ((mask & (1 << i)) != 0) sub.Add(arr[i]);
            }

            // Find minimum and maximum
            int mn = sub.Min();
            int mx = sub.Max();

            // Check if difference equals k
            if (mx - mn == k) res = Math.Max(res, sub.Count);
        }

        return res;
    }

//Driver Code Starts

    static void Main() {
        int[] arr = {2, 3, 6, 5, 3};
        int k = 3;
        Console.WriteLine(longestsub(arr, k));
    }
}

//Driver Code Ends
JavaScript
function longestsub(arr, k) {
    let n = arr.length;
    let res = 0;

    // There are 2^n possible subsequences
    for (let mask = 1; mask < (1 << n); mask++) {
        let sub = [];

        // Build subsequence for current mask
        for (let i = 0; i < n; i++) {
            if (mask & (1 << i)) sub.push(arr[i]);
        }

        // Find minimum and maximum
        let mn = Math.min(...sub);
        let mx = Math.max(...sub);

        // Check if difference equals k
        if (mx - mn === k) res = Math.max(res, sub.length);
    }

    return res;
}


//Driver Code Starts
// Driver code
let arr = [2, 3, 6, 5, 3];
let k = 3;
console.log(longestsub(arr, k));

//Driver Code Ends

Output
4

[Better Approach] Using HashMap - O(n log(n)) Time and O(n) Space

We want a subsequence, so the relative positions of elements do not matter. Only the values matter because we just need:

maxValue – minValue = k

Since subsequences allow picking elements from anywhere, we can sort the array without affecting the answer. After sorting, all values that lie between a and a + k appear in one continuous segment.

So for every value a, we just check whether a + k exists and find how long the segment from a to a + k is in the sorted array. The largest such segment gives the final subsequence length.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

//Driver Code Ends

int longestsub(vector<int> &arr, int k) {
    int n = arr.size();
    
    // sort to group close values together
    sort(arr.begin(), arr.end());
    
    // store the last index of every value
    map<int, int> m;
    for (int i = 0; i < n; i++) {
        m[arr[i]] = i;
    }

    int ans = 0;

    // for each value a, check if a+k exists
    for (int i = 0; i < n; i++) {
        int x = arr[i] + k;

        if (m.find(x) != m.end()) {
            
            // length of segment from a to a+k in sorted array
            ans = max(ans, m[x] - i + 1);
        }
    }

    return ans;
}

//Driver Code Starts

int main() {
    vector<int> arr = {2, 3, 6, 5, 3};
    int k = 3;

    cout << longestsub(arr, k) << endl;
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.TreeMap;
import java.util.Arrays;

class GFG {

//Driver Code Ends

    static int longestsub(int[] arr, int k) {
        int n = arr.length;

        // sort to group close values together
        Arrays.sort(arr);

        // store the last index of every value
        TreeMap<Integer, Integer> m = new TreeMap<>();
        for (int i = 0; i < n; i++) {
            m.put(arr[i], i);
        }

        int ans = 0;

        // for each value a, check if a+k exists
        for (int i = 0; i < n; i++) {
            int x = arr[i] + k;

            if (m.containsKey(x)) {

                // length of segment from a to a+k in sorted array
                ans = Math.max(ans, m.get(x) - i + 1);
            }
        }

        return ans;
    }

//Driver Code Starts

    public static void main(String[] args) {
        int[] arr = {2, 3, 6, 5, 3};
        int k = 3;

        System.out.println(longestsub(arr, k));
    }
}

//Driver Code Ends
Python
def longestsub(arr, k):
    n = len(arr)

    # sort to group close values together
    arr.sort()

    # store the last index of every value
    m = {}
    for i in range(n):
        m[arr[i]] = i

    ans = 0

    # for each value a, check if a+k exists
    for i in range(n):
        x = arr[i] + k

        if x in m:

            # length of segment from a to a+k in sorted array
            ans = max(ans, m[x] - i + 1)

    return ans


#Driver Code Starts
if __name__ == '__main__':
    arr = [2, 3, 6, 5, 3]
    k = 3
    print(longestsub(arr, k))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GFG {

//Driver Code Ends

    static int longestsub(int[] arr, int k) {
        int n = arr.Length;

        // sort to group close values together
        Array.Sort(arr);

        // store the last index of every value
        Dictionary<int, int> m = new Dictionary<int, int>();
        for (int i = 0; i < n; i++) {
            m[arr[i]] = i;
        }

        int ans = 0;

        // for each value a, check if a+k exists
        for (int i = 0; i < n; i++) {
            int x = arr[i] + k;

            if (m.ContainsKey(x)) {

                // length of segment from a to a+k in sorted array
                ans = Math.Max(ans, m[x] - i + 1);
            }
        }

        return ans;
    }

//Driver Code Starts

    static void Main() {
        int[] arr = {2, 3, 6, 5, 3};
        int k = 3;

        Console.WriteLine(longestsub(arr, k));
    }
}

//Driver Code Ends
JavaScript
function longestsub(arr, k) {
    let n = arr.length;

    // sort to group close values together
    arr.sort((a, b) => a - b);

    // store the last index of every value
    let m = new Map();
    for (let i = 0; i < n; i++) {
        m.set(arr[i], i);
    }

    let ans = 0;

    // for each value a, check if a+k exists
    for (let i = 0; i < n; i++) {
        let x = arr[i] + k;

        if (m.has(x)) {

            // length of segment from a to a+k in sorted array
            ans = Math.max(ans, m.get(x) - i + 1);
        }
    }

    return ans;
}


//Driver Code Starts
// Driver Code
let arr = [2, 3, 6, 5, 3];
let k = 3;

console.log(longestsub(arr, k));

//Driver Code Ends

Output
4

[Expected Approach] Using Two Pointers - O(n log(n)) Time and O(1) Space

In the above approach we can observer that once the array is sorted, any subsequence where max − min = k will lie within one continuous range.

So we use two pointers i and j to scan that range:

If arr[j] − arr[i] < k, expand the range by moving j.
If arr[j] − arr[i] > k, shrink the range by moving i.
If arr[j] − arr[i] == k, we have a valid window; update the answer and keep moving j to include every element equal to arr[i] + k.

This ensures we capture the longest possible window that satisfies the required difference.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//Driver Code Ends

int longestsub(vector<int> &arr, int k) {
    int n = arr.size();

    // sort the array to allow sliding-window traversal
    sort(arr.begin(), arr.end());

    int i = 0, j = 0, ans = 0;

    while (i < n && j < n) {

        int diff = arr[j] - arr[i];

        if (diff < k) {
            
            // need larger values, move j forward
            j++;
        } 
        else if (diff > k) {
           
            // window too wide, move i forward
            i++;
            
            // ensure j stays ahead
            if (i > j) {
                j = i;  
            }
        } 
        else {
            
            // diff == k → valid window
            ans = max(ans, j - i + 1);
            j++;       
        }
    }

    return ans;
}

//Driver Code Starts

int main() {
    vector<int> arr = {2, 3, 6, 5, 3};
    int k = 3;

    cout << longestsub(arr, k) << endl;

    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GFG {

//Driver Code Ends

    static int longestsub(int[] arr, int k) {
        int n = arr.length;

        // sort the array to allow sliding-window traversal
        Arrays.sort(arr);

        int i = 0, j = 0, ans = 0;

        while (i < n && j < n) {

            int diff = arr[j] - arr[i];

            if (diff < k) {
                // need larger values, move j forward
                j++;
            }
            else if (diff > k) {
              
                // window too wide, move i forward
                i++;

                // ensure j stays ahead
                if (i > j) {
                    j = i;
                }
            }
            else {
             
                // diff == k → valid window
                ans = Math.max(ans, j - i + 1);
                j++;
            }
        }

        return ans;
    }

//Driver Code Starts

    public static void main(String[] args) {
        int[] arr = {2, 3, 6, 5, 3};
        int k = 3;

        System.out.println(longestsub(arr, k));
    }
}

//Driver Code Ends
Python
def longestsub(arr, k):
    n = len(arr)

    # sort the array to allow sliding-window traversal
    arr.sort()

    i = 0
    j = 0
    ans = 0

    while i < n and j < n:

        diff = arr[j] - arr[i]

        if diff < k:
            # need larger values, move j forward
            j += 1
        elif diff > k:
            # window too wide, move i forward
            i += 1

            # ensure j stays ahead
            if i > j:
                j = i
        else:
            # diff == k → valid window
            ans = max(ans, j - i + 1)
            j += 1

    return ans


#Driver Code Starts
if __name__ == '__main__':
    arr = [2, 3, 6, 5, 3]
    k = 3
    print(longestsub(arr, k))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG {

//Driver Code Ends

    static int longestsub(int[] arr, int k) {
        int n = arr.Length;

        // sort the array to allow sliding-window traversal
        Array.Sort(arr);

        int i = 0, j = 0, ans = 0;

        while (i < n && j < n) {

            int diff = arr[j] - arr[i];

            if (diff < k) {
                // need larger values, move j forward
                j++;
            }
            else if (diff > k) {
                // window too wide, move i forward
                i++;

                // ensure j stays ahead
                if (i > j) {
                    j = i;
                }
            }
            else {
                // diff == k → valid window
                ans = Math.Max(ans, j - i + 1);
                j++;
            }
        }

        return ans;
    }

//Driver Code Starts

    static void Main() {
        int[] arr = {2, 3, 6, 5, 3};
        int k = 3;

        Console.WriteLine(longestsub(arr, k));
    }
}

//Driver Code Ends
JavaScript
function longestsub(arr, k) {
    let n = arr.length;

    // sort the array to allow sliding-window traversal
    arr.sort((a, b) => a - b);

    let i = 0, j = 0, ans = 0;

    while (i < n && j < n) {

        let diff = arr[j] - arr[i];

        if (diff < k) {
            // need larger values, move j forward
            j++;
        }
        else if (diff > k) {
            // window too wide, move i forward
            i++;

            // ensure j stays ahead
            if (i > j) {
                j = i;
            }
        }
        else {
            // diff == k → valid window
            ans = Math.max(ans, j - i + 1);
            j++;
        }
    }

    return ans;
}


//Driver Code Starts
// Driver Code
let arr = [2, 3, 6, 5, 3];
let k = 3;
console.log(longestsub(arr, 3));

//Driver Code Ends

Output
4



Explore