Open In App

Longest Subsequence such that difference between adjacent elements is either A or B

Last Updated : 20 Dec, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr of size N, and two integers A and B. The task is to find the length of the longest subsequence with the difference between adjacent elements as either A or B.

Example:

Input  : arr[]={ 5, 5, 5, 10, 8, 6, 12, 13 }, A=0, B=1
Output : 4
Explanation : Maximum length subsequence is {5,5,5,6}

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

 

Approach: On taking a closer look at the problem, the problem is similar to Longest Consecutive Subsequence. The only difference between them is now we have to count for the elements with differences A or B instead of 1. Now, to solve this problem, follow the below steps:

  1. Create a map, which will store each element as the key, and the length of the longest subsequence ending with arr[i] as the value.
  2. Now, traverse the array arr, and for each element arr[i]:
    • Search for arr[i]-A, arr[i]+A, arr[i]-B, arr[i]+B in the map.
    • If they are present find the maximum of all and +1 in that to get the maximum length of subsequence.
  3. Find the maximum value in the map, and return it as the answer

Below is the implementation of the above approach.

C++




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the length of
// longest common subsequence with
// difference between the consecutive
// element is either A or B
int maxSubsequence(vector<int>& arr, int A, int B)
{
    int N = arr.size();
 
    int ans = 1;
 
    // Map to store the length of longest subsequence
    // ending with arr[i]
    unordered_map<int, int> mp;
 
    for (int i = 0; i < N; ++i) {
        int aa = 1;
 
        // If arr[i]-A exists
        if (mp.count(arr[i] - A)) {
            aa = mp[arr[i] - A] + 1;
        }
 
        // If arr[i]+A exists
        if (mp.count(arr[i] + A)) {
            aa = max(aa, mp[arr[i] + A] + 1);
        }
 
        // If arr[i]-B exists
        if (mp.count(arr[i] - B)) {
            aa = max(aa, mp[arr[i] - B] + 1);
        }
 
        // If arr[i]+B exists
        if (mp.count(arr[i] + B)) {
            aa = max(aa, mp[arr[i] + B] + 1);
        }
 
        mp[arr[i]] = aa;
        ans = max(ans, mp[arr[i]]);
    }
 
    return ans;
}
 
// Driver Code
int main()
{
 
    vector<int> arr = { 5, 5, 5, 10, 8, 6, 12, 13 };
    int A = 0, B = 1;
    cout << maxSubsequence(arr, A, B);
    return 0;
}


Java




// Java code for the above approach
import java.util.*;
 
class GFG{
 
// Function to find the length of
// longest common subsequence with
// difference between the consecutive
// element is either A or B
static int maxSubsequence(int []arr, int A, int B)
{
    int N = arr.length;
 
    int ans = 1;
 
    // Map to store the length of longest subsequence
    // ending with arr[i]
    HashMap<Integer,Integer> mp = new HashMap<Integer,Integer>();
 
    for (int i = 0; i < N; ++i) {
        int aa = 1;
 
        // If arr[i]-A exists
        if (mp.containsKey(arr[i] - A)) {
            aa = mp.get(arr[i] - A) + 1;
        }
 
        // If arr[i]+A exists
        if (mp.containsKey(arr[i] + A)) {
            aa = Math.max(aa, mp.get(arr[i] + A) + 1);
        }
 
        // If arr[i]-B exists
        if (mp.containsKey(arr[i] - B)) {
            aa = Math.max(aa, mp.get(arr[i] - B) + 1);
        }
 
        // If arr[i]+B exists
        if (mp.containsKey(arr[i] + B)) {
            aa = Math.max(aa, mp.get(arr[i] + B) + 1);
        }
        mp.put(arr[i], aa);
        ans = Math.max(ans, mp.get(arr[i]));
    }
 
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
 
    int []arr = { 5, 5, 5, 10, 8, 6, 12, 13 };
    int A = 0, B = 1;
    System.out.print(maxSubsequence(arr, A, B));
}
}
 
// This code is contributed by 29AjayKumar


Python3




# python code for the above approach
 
# Function to find the length of
# longest common subsequence with
# difference between the consecutive
# element is either A or B
def maxSubsequence(arr, A, B):
    N = len(arr)
    ans = 1
 
    # Map to store the length of longest subsequence
    # ending with arr[i]
    mp = {}
 
    for i in range(0, N):
        aa = 1
 
        # If arr[i]-A exists
        if ((arr[i] - A) in mp):
            aa = mp[arr[i] - A] + 1
 
        # If arr[i]+A exists
        if ((arr[i] + A) in mp):
            aa = max(aa, mp[arr[i] + A] + 1)
 
        # If arr[i]-B exists
        if ((arr[i] - B) in mp):
            aa = max(aa, mp[arr[i] - B] + 1)
 
        # If arr[i]+B exists
        if ((arr[i] + B) in mp):
            aa = max(aa, mp[arr[i] + B] + 1)
 
        mp[arr[i]] = aa
        ans = max(ans, mp[arr[i]])
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    arr = [5, 5, 5, 10, 8, 6, 12, 13]
 
    A = 0
    B = 1
 
    print(maxSubsequence(arr, A, B))
 
    # This code is contributed by rakeshsahni


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
class GFG {
 
  // Function to find the length of
  // longest common subsequence with
  // difference between the consecutive
  // element is either A or B
  static int maxSubsequence(int[] arr, int A, int B)
  {
    int N = arr.Length;
 
    int ans = 1;
 
    // Map to store the length of longest subsequence
    // ending with arr[i]
    Dictionary<int, int> mp
      = new Dictionary<int, int>();
 
    for (int i = 0; i < N; ++i) {
      int aa = 1;
 
      // If arr[i]-A exists
      if (mp.ContainsKey(arr[i] - A)) {
        aa = mp[arr[i] - A] + 1;
      }
 
      // If arr[i]+A exists
      if (mp.ContainsKey(arr[i] + A)) {
        aa = Math.Max(aa, mp[arr[i] + A] + 1);
      }
 
      // If arr[i]-B exists
      if (mp.ContainsKey(arr[i] - B)) {
        aa = Math.Max(aa, mp[arr[i] - B] + 1);
      }
 
      // If arr[i]+B exists
      if (mp.ContainsKey(arr[i] + B)) {
        aa = Math.Max(aa, mp[arr[i] + B] + 1);
      }
      mp[arr[i]] = aa;
      ans = Math.Max(ans, mp[arr[i]]);
    }
 
    return ans;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
 
    int[] arr = { 5, 5, 5, 10, 8, 6, 12, 13 };
    int A = 0, B = 1;
    Console.WriteLine(maxSubsequence(arr, A, B));
  }
}
 
// This code is contributed by ukasp.


Javascript




<script>
        // JavaScript code for the above approach
 
        // Function to find the length of
        // longest common subsequence with
        // difference between the consecutive
        // element is either A or B
        function maxSubsequence(arr, A, B) {
            let N = arr.length;
 
            let ans = 1;
 
            // Map to store the length of longest subsequence
            // ending with arr[i]
            let mp = new Map();
 
            for (let i = 0; i < N; ++i) {
                let aa = 1;
 
                // If arr[i]-A exists
                if (mp.has(arr[i] - A)) {
                    aa = mp.get(arr[i] - A) + 1;
                }
 
                // If arr[i]+A exists
                if (mp.has(arr[i] + A)) {
                    aa = Math.max(aa, mp.get(arr[i] + A) + 1);
                }
 
                // If arr[i]-B exists
                if (mp.has(arr[i] - B)) {
                    aa = Math.max(aa, mp.get(arr[i] - B) + 1);
                }
 
                // If arr[i]+B exists
                if (mp.has(arr[i] + B)) {
                    aa = Math.max(aa, mp.get(arr[i] + B) + 1);
                }
 
                mp.set(arr[i], aa);
                ans = Math.max(ans, mp.get(arr[i]));
            }
 
            return ans;
        }
 
        // Driver Code
        let arr = [5, 5, 5, 10, 8, 6, 12, 13]
        let A = 0, B = 1;
        document.write(maxSubsequence(arr, A, B));
 
  // This code is contributed by Potta Lokesh
    </script>


 
 

Output

4

 

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

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads