Print longest Subsequence such that difference between adjacent elements is K
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; } |
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> |
4 6 8
Time Complexity: O(N)
Auxiliary Space: O(N)