Longest Subsequence with Difference k
Last Updated :
15 Nov, 2025
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
[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
[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
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem