Open In App

Print longest Subsequence such that difference between adjacent elements is K

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, and integer K. The task is to find the longest subsequence with the difference between adjacent elements as K

Examples:

Input: arr[] = { 5, 5, 5, 10, 8, 6, 12, 13 }, K = 1
Output: {5, 6}

Input: arr[] = {4, 6, 7, 8, 9, 8, 12, 14, 17, 15}, K = 2
Output: {4, 6, 8}

 

Approach: The task can be solved with the help of dynamic programming. Every element of the array can be considered as the last element of a subsequence. For every element, the idea is to store the length of the longest subsequence having differences between adjacent elements K and the predecessor of the current element on that subsequence. Follow the steps mentioned below to implement the approach.

  • Create a map, to store the last occurrence of each element.
  • Create an array of pairs dp[] to store the length of longest subsequence ending at an index and the predecessor of that index.
  • Now, traverse the array arr[], and for each element arr[i]:
    • Search for (arr[i] – K), (arr[i] + K) in the map.
    • If they are present, then find out the subsequence with maximum length and store the length and predecessor in dp[i].
  • Print the longest subsequence with help of predecessors stored in the array dp[].

Below is the implementation of the above approach.

C++




// C++ program to implement above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the longest subsequence
vector<int> maxSubsequence(vector<int>& arr, int K)
{
    int N = arr.size();
 
    // Declaring the dp[] array and map
    vector<pair<int, int> > dp(N, { 1, -1 });
    unordered_map<int, int> mp;
    mp[arr[0]] = 1;
 
    // Initialise variable to store
    // maximum length and last index of
    // the longest subsequence
    int maxlen = 1, ind = 0;
 
    // Loop to find out the longest
    // subsequence
    for (int i = 1; i < N; i++) {
 
        // If arr[i]-K is present in the part
        // of array visited till now
        if (mp.count(arr[i] - K)) {
            dp[i] = { dp[mp[arr[i] - K] - 1].first + 1,
                      mp[arr[i] - K] - 1 };
        }
 
        // If arr[i]+K is present in the part
        // of array visited till now
        if (mp.count(arr[i] + K)) {
            if (dp[i].first
                < dp[mp[arr[i] + K] - 1].first + 1) {
                dp[i].first
                    = dp[mp[arr[i] + K] - 1].first + 1;
                dp[i].second = mp[arr[i] + K] - 1;
            }
        }
 
        // If maximum length increase store
        // the length and current index as the
        // last index of longest subsequence
        if (maxlen < dp[i].first) {
            maxlen = dp[i].first;
            ind = i;
        }
        mp[arr[i]] = i + 1;
    }
 
    // Declare vector to store the
    // longest subsequence
    vector<int> v;
 
    // Loop to generate the subsequence
    while (ind >= 0) {
        v.push_back(arr[ind]);
        ind = dp[ind].second;
    }
    reverse(v.begin(), v.end());
    return v;
}
 
// Driver code
int main()
{
    vector<int> arr = { 4, 6, 7, 8, 9, 8, 12,
                       14, 17, 15 };
    int K = 2;
 
    // Calling function to find
    // longest subsequence
    vector<int> longSubseq =
        maxSubsequence(arr, K);
    for (auto i : longSubseq)
        cout << i << " ";
    cout << endl;
 
    return 0;
}


Java




// Java program to implement above approach
import java.util.*;
 
class Main {
   
  static class Pair<K, V> {
        public K key;
        public V value;
 
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
 
        public K getKey() {
            return key;
        }
 
        public V getValue() {
            return value;
        }
    }
 
   
    // Function to find the longest subsequence
    public static ArrayList<Integer> maxSubsequence(ArrayList<Integer> arr,
                                                                       int K) {
        int N = arr.size();
 
        // Declaring the dp[] array and map
        ArrayList<Pair<Integer, Integer>> dp = new ArrayList<Pair<Integer,
                                                                  Integer>>(N);
        for (int i = 0; i < N; i++) {
            dp.add(new Pair<Integer, Integer>(1, -1));
        }
        HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>();
        mp.put(arr.get(0), 1);
 
        // Initialise variable to store
        // maximum length and last index of
        // the longest subsequence
        int maxlen = 1, ind = 0;
 
        // Loop to find out the longest
        // subsequence
        for (int i = 1; i < N; i++) {
 
            // If arr[i]-K is present in the part
            // of array visited till now
            if (mp.containsKey(arr.get(i) - K)) {
                dp.set(i, new Pair<Integer,
                        Integer>(dp.get(mp.get(arr.get(i) - K) - 1).getKey() + 1,
                        mp.get(arr.get(i) - K) - 1));
            }
 
            // If arr[i]+K is present in the part
            // of array visited till now
            if (mp.containsKey(arr.get(i) + K)) {
                if (dp.get(i).getKey() <
                    dp.get(mp.get(arr.get(i) + K) - 1).getKey() + 1) {
                    dp.set(i, new Pair<Integer,
                      Integer>(dp.get(mp.get(arr.get(i) + K) - 1).getKey() + 1,
                            mp.get(arr.get(i) + K) - 1));
                }
            }
 
            // If maximum length increase store
            // the length and current index as the
            // last index of longest subsequence
            if (maxlen < dp.get(i).getKey()) {
                maxlen = dp.get(i).getKey();
                ind = i;
            }
            mp.put(arr.get(i), i + 1);
        }
 
        // Declare vector to store the
        // longest subsequence
        ArrayList<Integer> v = new ArrayList<Integer>();
 
        // Loop to generate the subsequence
        while (ind >= 0) {
            v.add(arr.get(ind));
            ind = dp.get(ind).getValue();
        }
        Collections.reverse(v);
        return v;
    }
 
    // Driver code
    public static void main(String[] args) {
        ArrayList<Integer> arr =
          new ArrayList<Integer>(Arrays.asList(4, 6, 7, 8, 9, 8, 12, 14, 17, 15));
        int K = 2;
 
        // Calling function to find
        // longest subsequence
        ArrayList<Integer> longSubseq = maxSubsequence(arr, K);
    for (int i : longSubseq)
        System.out.print(i + " ");
    System.out.println();
       
    }
}


Python3




# Python program to implement above approach
 
# Function to find the longest subsequence
def maxSubsequence(arr, K):
     
    N = len(arr)
     
    # Declaring the dp[] array and map
    dp = [[1, -1] for i in range(N)]
    mp = {}
    mp[arr[0]] = 1
     
    # Initialise variable to store
    # maximum length and last index of
    # the longest subsequence
    maxlen = 1
    ind = 0
     
    # Loop to find out the longest
    # subsequence
    for i in range(1,N):
         
        # If arr[i]-K is present in the part
        # of array visited till now
        if (arr[i] - K) in mp:
            dp[i] =  [dp[mp[arr[i] - K] - 1][0] + 1, mp[arr[i] - K] - 1]
             
        # If arr[i]+K is present in the part
        # of array visited till now
        if (arr[i] + K) in mp:
            if (dp[i][0] < dp[mp[arr[i] + K] - 1][0] + 1):
                dp[i][0]= dp[mp[arr[i] + K] - 1][0] + 1
                dp[i][1] = mp[arr[i] + K] - 1
                 
        # If maximum length increase store
        # the length and current index as the
        # last index of longest subsequence
        if (maxlen < dp[i][0]):
            maxlen = dp[i][0]
            ind = i
             
        mp[arr[i]] = i + 1
         
    # Declare vector to store the
    # longest subsequence
    v =[]
     
    # Loop to generate the subsequence
    while (ind >= 0):
        v.append(arr[ind])
        ind = dp[ind][1]
         
    v.reverse()
    return v
 
# Driver code
arr =  [4, 6, 7, 8, 9, 8, 12, 14, 17, 15 ]
K = 2
 
# Calling function to find
# longest subsequence
longSubseq = maxSubsequence(arr, K)
for i in longSubseq:
    print(i , end= " ")
print()
 
# This code is contributed by Shubham Singh


Javascript




<script>
 
// JavaScript program to implement above approach
 
// Function to find the longest subsequence
function maxSubsequence(arr, K){
     
    let N = arr.length
     
    // Declaring the dp[] array and map
    let dp = new Array(N).fill([]).map(()=>[1,-1])
    let mp = new Map()
    mp.set(arr[0], 1)
     
    // Initialise variable to store
    // maximum length and last index of
    // the longest subsequence
    let maxlen = 1
    let ind = 0
     
    // Loop to find out the longest
    // subsequence
    for(let i=1;i<N;i++){
         
        // If arr[i]-K is present in the part
        // of array visited till now
        if(mp.has(arr[i] - K)== true)
            dp[i] = [dp[mp.get(arr[i] - K) - 1][0] + 1, mp.get(arr[i] - K) - 1]
             
        // If arr[i]+K is present in the part
        // of array visited till now
        if(mp.has(arr[i] + K)){
            if (dp[i][0] < dp[mp.get(arr[i] + K) - 1][0] + 1){
                dp[i][0]= dp[mp.get(arr[i] + K) - 1][0] + 1
                dp[i][1] = mp.get(arr[i] + K) - 1
            }
        }
                 
        // If maximum length increase store
        // the length and current index as the
        // last index of longest subsequence
        if (maxlen < dp[i][0]){
            maxlen = dp[i][0]
            ind = i
        }
             
        mp.set(arr[i], i + 1)
    }
         
    // Declare vector to store the
    // longest subsequence
    let v =[]
     
    // Loop to generate the subsequence
    while (ind >= 0){
        v.push(arr[ind])
        ind = dp[ind][1]
    }
         
    v.reverse()
    return v
}
 
// Driver code
let arr = [4, 6, 7, 8, 9, 8, 12, 14, 17, 15 ]
let K = 2
 
// Calling function to find
// longest subsequence
let longSubseq = maxSubsequence(arr, K)
for(let i of longSubseq)
    document.write(i ," ")
document.write("</br>")
 
// This code is contributed by shinjanpatra
 
</script>


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    // Function to find the longest subsequence
    static List<int> MaxSubsequence(List<int> arr, int K)
    {
        int N = arr.Count();
 
        // Declaring the dp[] array and map
        List<(int, int)> dp = Enumerable.Repeat((1, -1), N).ToList();
        Dictionary<int, int> mp = new Dictionary<int, int>();
        mp[arr[0]] = 1;
 
        // Initialise variable to store
        // maximum length and last index of
        // the longest subsequence
        int maxlen = 1, ind = 0;
 
        // Loop to find out the longest
        // subsequence
        for (int i = 1; i < N; i++)
        {
            // If arr[i]-K is present in the part
            // of array visited till now
            if (mp.ContainsKey(arr[i] - K))
            {
                dp[i] = (dp[mp[arr[i] - K] - 1].Item1 + 1, mp[arr[i] - K] - 1);
            }
 
            // If arr[i]+K is present in the part
            // of array visited till now
            if (mp.ContainsKey(arr[i] + K))
            {
                if (dp[i].Item1 < dp[mp[arr[i] + K] - 1].Item1 + 1)
                {
                    dp[i] = (dp[mp[arr[i] + K] - 1].Item1 + 1, mp[arr[i] + K] - 1);
                }
            }
 
            // If maximum length increase store
            // the length and current index as the
            // last index of longest subsequence
            if (maxlen < dp[i].Item1)
            {
                maxlen = dp[i].Item1;
                ind = i;
            }
            mp[arr[i]] = i + 1;
        }
 
        // Declare list to store the
        // longest subsequence
        List<int> v = new List<int>();
 
        // Loop to generate the subsequence
        while (ind >= 0)
        {
            v.Add(arr[ind]);
            ind = dp[ind].Item2;
        }
        v.Reverse();
        return v;
    }
 
    // Driver code
    static void Main(string[] args)
    {
        List<int> arr = new List<int>() { 4, 6, 7, 8, 9, 8, 12, 14, 17, 15 };
        int K = 2;
 
        // Calling function to find
        // longest subsequence
        List<int> longSubseq = MaxSubsequence(arr, K);
        foreach (var i in longSubseq)
            Console.Write(i + " ");
        Console.WriteLine();
    }
}


Output

4 6 8 

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

 



Last Updated : 24 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads