Given an array of size n. The task is to find the longest subsequence such that difference between adjacents is one. Time Complexity of O(n) is required.
Examples:
Input : arr[] = {10, 9, 4, 5, 4, 8, 6} Output : 3 As longest subsequences with difference 1 are, "10, 9, 8", "4, 5, 4" and "4, 5, 6". Input : arr[] = {1, 2, 3, 2, 3, 7, 2, 1} Output : 7 As longest consecutive sequence is "1, 2, 3, 2, 3, 2, 1".
Method 1: Previously an approach having time complexity of O(n2) have been discussed in this post.
Method 2 (Efficient Approach): The idea is to create a hash map having tuples in the form (ele, len), where len denotes the length of the longest subsequence ending with the element ele. Now, for each element arr[i] we can find the length of the values arr[i]-1 and arr[i]+1 in the hash table and consider the maximum among them. Let this maximum value be max. Now, the length of longest subsequence ending with arr[i] would be max+1. Update this length along with the element arr[i] in the hash table. Finally, the element having the maximum length in the hash table gives the longest length subsequence.
// C++ implementation to find longest subsequence // such that difference between adjacents is one #include <bits/stdc++.h> using namespace std;
// function to find longest subsequence such // that difference between adjacents is one int longLenSub( int arr[], int n)
{ // hash table to map the array element with the
// length of the longest subsequence of which
// it is a part of and is the last element of
// that subsequence
unordered_map< int , int > um;
// to store the longest length subsequence
int longLen = 0;
// traverse the array elements
for ( int i=0; i<n; i++)
{
// initialize current length
// for element arr[i] as 0
int len = 0;
// if 'arr[i]-1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.find(arr[i]-1) != um.end() &&
len < um[arr[i]-1])
len = um[arr[i]-1];
// if 'arr[i]+1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.find(arr[i]+1) != um.end() &&
len < um[arr[i]+1])
len = um[arr[i]+1];
// update arr[i] subsequence length in 'um'
um[arr[i]] = len + 1;
// update longest length
if (longLen < um[arr[i]])
longLen = um[arr[i]];
}
// required longest length subsequence
return longLen;
} // Driver program to test above int main()
{ int arr[] = {1, 2, 3, 4, 5, 3, 2};
int n = sizeof (arr) / sizeof (arr[0]);
cout << "Longest length subsequence = "
<< longLenSub(arr, n);
return 0;
} |
// Java implementation to find longest subsequence // such that difference between adjacents is one import java.util.*;
class GFG
{ // function to find longest subsequence such // that difference between adjacents is one static int longLenSub( int []arr, int n)
{ // hash table to map the array element with the
// length of the longest subsequence of which
// it is a part of and is the last element of
// that subsequence
HashMap<Integer,
Integer> um = new HashMap<Integer,
Integer>();
// to store the longest length subsequence
int longLen = 0 ;
// traverse the array elements
for ( int i = 0 ; i < n; i++)
{
// initialize current length
// for element arr[i] as 0
int len = 0 ;
// if 'arr[i]-1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.containsKey(arr[i] - 1 ) &&
len < um.get(arr[i] - 1 ))
len = um.get(arr[i] - 1 );
// if 'arr[i]+1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.containsKey(arr[i] + 1 ) &&
len < um.get(arr[i] + 1 ))
len = um.get(arr[i] + 1 );
// update arr[i] subsequence length in 'um'
um. put(arr[i], len + 1 );
// update longest length
if (longLen < um.get(arr[i]))
longLen = um.get(arr[i]);
}
// required longest length subsequence
return longLen;
} // Driver Code public static void main(String[] args)
{ int [] arr = { 1 , 2 , 3 , 4 , 5 , 3 , 2 };
int n = arr.length;
System.out.println( "Longest length subsequence = " +
longLenSub(arr, n));
} } // This code is contributed by Princi Singh |
# Python3 implementation to find longest # subsequence such that difference between # adjacents is one from collections import defaultdict
# function to find longest subsequence such # that difference between adjacents is one def longLenSub(arr, n):
# hash table to map the array element
# with the length of the longest
# subsequence of which it is a part of
# and is the last element of that subsequence
um = defaultdict( lambda : 0 )
longLen = 0
for i in range (n):
# / initialize current length
# for element arr[i] as 0
len1 = 0
# if 'arr[i]-1' is in 'um' and its length
# of subsequence is greater than 'len'
if (arr[i - 1 ] in um and
len1 < um[arr[i] - 1 ]):
len1 = um[arr[i] - 1 ]
# f 'arr[i]+1' is in 'um' and its length
# of subsequence is greater than 'len'
if (arr[i] + 1 in um and
len1 < um[arr[i] + 1 ]):
len1 = um[arr[i] + 1 ]
# update arr[i] subsequence
# length in 'um'
um[arr[i]] = len1 + 1
# update longest length
if longLen < um[arr[i]]:
longLen = um[arr[i]]
# required longest length
# subsequence
return longLen
# Driver code arr = [ 1 , 2 , 3 , 4 , 5 , 3 , 2 ]
n = len (arr)
print ( "Longest length subsequence =" ,
longLenSub(arr, n))
# This code is contributed by Shrikant13 |
// C# implementation to find longest subsequence // such that difference between adjacents is one using System;
using System.Collections.Generic;
class GFG
{ // function to find longest subsequence such // that difference between adjacents is one static int longLenSub( int []arr, int n)
{ // hash table to map the array element with the
// length of the longest subsequence of which
// it is a part of and is the last element of
// that subsequence
Dictionary< int ,
int > um = new Dictionary< int ,
int >();
// to store the longest length subsequence
int longLen = 0;
// traverse the array elements
for ( int i = 0; i < n; i++)
{
// initialize current length
// for element arr[i] as 0
int len = 0;
// if 'arr[i]-1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.ContainsKey(arr[i] - 1) &&
len < um[arr[i] - 1])
len = um[arr[i] - 1];
// if 'arr[i]+1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.ContainsKey(arr[i] + 1) &&
len < um[arr[i] + 1])
len = um[arr[i] + 1];
// update arr[i] subsequence length in 'um'
um[arr[i]] = len + 1;
// update longest length
if (longLen < um[arr[i]])
longLen = um[arr[i]];
}
// required longest length subsequence
return longLen;
} // Driver program to test above static void Main()
{ int [] arr = {1, 2, 3, 4, 5, 3, 2};
int n = arr.Length;
Console.Write( "Longest length subsequence = " +
longLenSub(arr, n));
} } // This code is contributed by Mohit Kumar |
<script> // JavaScript implementation to find longest subsequence // such that difference between adjacents is one // function to find longest subsequence such
// that difference between adjacents is one function longLenSub(arr,n)
{
// hash table to map the array element with the
// length of the longest subsequence of which
// it is a part of and is the last element of
// that subsequence
let um = new Map();
// to store the longest length subsequence
let longLen = 0;
// traverse the array elements
for (let i = 0; i < n; i++)
{
// initialize current length
// for element arr[i] as 0
let len = 0;
// if 'arr[i]-1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.has(arr[i] - 1) &&
len < um.get(arr[i] - 1))
len = um.get(arr[i] - 1);
// if 'arr[i]+1' is in 'um' and its length
// of subsequence is greater than 'len'
if (um.has(arr[i] + 1) &&
len < um.get(arr[i] + 1))
len = um.get(arr[i] + 1);
// update arr[i] subsequence length in 'um'
um.set(arr[i], len + 1);
// update longest length
if (longLen < um.get(arr[i]))
longLen = um.get(arr[i]);
}
// required longest length subsequence
return longLen;
}
// Driver Code
let arr=[1, 2, 3, 4, 5, 3, 2];
let n = arr.length;
document.write( "Longest length subsequence = " +
longLenSub(arr, n));
// This code is contributed by unknown2108 </script> |
Output:
Longest length subsequence = 6
Time Complexity: O(n).
Auxiliary Space: O(n).