Longest subsequence forming an Arithmetic Progression (AP)

14 Jun, 2021
Given an array arr[] consisting of N integers, the task is to find the length of the longest subsequence that forms an Arithmetic Progression.
Examples:
Input: arr[] = {5, 10, 15, 20, 25, 30}Output: 6Explanation:The whole set is in AP having common difference = 5.Therefore, the length is 4.
Input: arr[] = { 20, 1, 15, 3, 10, 5, 8 }Output: 4Explanation:The longest subsequence having the same difference is { 20, 15, 10, 5 }.The above subsequence has same difference for every consecutive pairs i.e., (15 – 20) = (10 – 15) = (5 – 10) = -5.Therefore, the length is 4.
Naive Approach: The simplest approach to solve the problem is to generate all the possible subsequences of the given array and print the length of the longest subsequence having the same difference between adjacent pairs of elements.Time 
Complexity: O(N*2N) Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized using Dynamic Programming. Below are the steps:
Initialize an auxiliary matrix dp[][] where dp[i][j] denotes the length of subsequence starting at i and having a common difference as j.Iterate over the array using nested loops i from N – 1 till 0 and j from i+1 to N.Assume that arr[i] and arr[j] are the first two elements of the sequence and let their difference be d.Now, two cases arise:dp[j][d] = 0: No such sequence exists that starts with arr[j] and has its difference as d.In this case dp[i][d] = 2, as we can have only arr[i] and arr[j] in the sequence.dp[j][d] > 0: A sequence exists that starts with arr[j] and has difference between adjacent elements as d.In this case, the relation is dp[i][d] = 1 + dp[j][d].Finally, print the maximum length of all subsequences formed.
Initialize an auxiliary matrix dp[][] where dp[i][j] denotes the length of subsequence starting at i and having a common difference as j.
Iterate over the array using nested loops i from N – 1 till 0 and j from i+1 to N.Assume that arr[i] and arr[j] are the first two elements of the sequence and let their difference be d.Now, two cases arise:dp[j][d] = 0: No such sequence exists that starts with arr[j] and has its difference as d.In this case dp[i][d] = 2, as we can have only arr[i] and arr[j] in the sequence.dp[j][d] > 0: A sequence exists that starts with arr[j] and has difference between adjacent elements as d.In this case, the relation is dp[i][d] = 1 + dp[j][d].
Assume that arr[i] and arr[j] are the first two elements of the sequence and let their difference be d.
Now, two cases arise:dp[j][d] = 0: No such sequence exists that starts with arr[j] and has its difference as d.In this case dp[i][d] = 2, as we can have only arr[i] and arr[j] in the sequence.dp[j][d] > 0: A sequence exists that starts with arr[j] and has difference between adjacent elements as d.In this case, the relation is dp[i][d] = 1 + dp[j][d].
dp[j][d] = 0: No such sequence exists that starts with arr[j] and has its difference as d.In this case dp[i][d] = 2, as we can have only arr[i] and arr[j] in the sequence.dp[j][d] > 0: A sequence exists that starts with arr[j] and has difference between adjacent elements as d.In this case, the relation is dp[i][d] = 1 + dp[j][d].
dp[j][d] = 0: No such sequence exists that starts with arr[j] and has its difference as d.In this case dp[i][d] = 2, as we can have only arr[i] and arr[j] in the sequence.
dp[j][d] > 0: A sequence exists that starts with arr[j] and has difference between adjacent elements as d.In this case, the relation is dp[i][d] = 1 + dp[j][d].
Finally, print the maximum length of all subsequences formed.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach #include <bits/stdc++.h>using namespace std; // Function that finds the longest// arithmetic subsequence having the// same absolute differenceint lenghtOfLongestAP(int A[], int n){     // Stores the length of sequences    // having same difference    unordered_map<int,                  unordered_map<int, int> >        dp;     // Stores the resultant length    int res = 2;     // Iterate over the array    for (int i = 0; i < n; ++i) {         for (int j = i + 1; j < n; ++j) {             int d = A[j] - A[i];             // Update length of subsequence            dp[d][j] = dp[d].count(i)                           ? dp[d][i] + 1                           : 2;             res = max(res, dp[d][j]);        }    }     // Return res    return res;} // Driver Codeint main(){    // Given array arr[]    int arr[] = { 20, 1, 15, 3, 10, 5, 8 };     int N = sizeof(arr) / sizeof(arr[0]);     // Function Call    cout << lenghtOfLongestAP(arr, N);    return 0;}
// Java program for the above approachimport java.io.*;import java.util.*; class GFG{ // Function that finds the longest// arithmetic subsequence having the// same absolute differencestatic int lenghtOfLongestAP(int A[], int n){         // Stores the length of sequences    // having same difference    Map<Integer,    Map<Integer,        Integer>> dp = new HashMap<Integer,                               Map<Integer,                                   Integer>>();       // Stores the resultant length    int res = 2;     // Iterate over the array    for(int i = 0; i < n; ++i)    {        for(int j = i + 1; j < n; ++j)        {            int d = A[j] - A[i];            Map<Integer, Integer> temp;             // Update length of subsequence            if (dp.containsKey(d))            {                temp = dp.get(d);                 if (temp.containsKey(i))                    temp.put(j, temp.get(i) + 1);                else                    temp.put(j, 2);            }            else            {                temp = new HashMap<Integer, Integer>();                temp.put(j, 2);            }            dp.put(d, temp);            res = Math.max(res, temp.get(j));        }    }         // Return res    return res;} // Driver Codepublic static void main(String[] args){         // Given array arr[]    int arr[] = { 20, 1, 15, 3, 10, 5, 8 };     int N = arr.length;     // Function Call    System.out.println(lenghtOfLongestAP(arr, N));}} // This code is contributed by jithin
# Python3 program for the above approach # Function that finds the longest# arithmetic subsequence having the# same absolute differencedef lenghtOfLongestAP(A, n) :     # Stores the length of sequences    # having same difference    dp = {}     # Stores the resultant length    res = 2     # Iterate over the array    for i in range(n) :         for j in range(i + 1, n) :             d = A[j] - A[i]             # Update length of subsequence            if d in dp :                if i in dp[d] :                    dp[d][j] = dp[d][i] + 1                else :                    dp[d][j] = 2            else :                dp[d] = {}                dp[d][j] = 2             if d in dp :                if j in dp[d] :                    res = max(res, dp[d][j])     # Return res    return res # Given array arr[]arr = [ 20, 1, 15, 3, 10, 5, 8 ] N = len(arr) # Function Callprint(lenghtOfLongestAP(arr, N)) # This code is contributed by divyeshrabadiya07
// C# program for the above approachusing System;using System.Collections.Generic;  class GFG{   // Function that finds the longest// arithmetic subsequence having the// same absolute differencestatic int lenghtOfLongestAP(int []A, int n){       // Stores the length of sequences    // having same difference    Dictionary<int,    Dictionary<int, int>> dp = new Dictionary<int,                                   Dictionary<int, int>>();       // Stores the resultant length    int res = 2;      // Iterate over the array    for(int i = 0; i < n; ++i)    {        for(int j = i + 1; j < n; ++j)        {            int d = A[j] - A[i];              // Update length of subsequence            if (dp.ContainsKey(d))            {                 if (dp[d].ContainsKey(i))                {                    dp[d][j] = dp[d][i] + 1;                   }                else                {                    dp[d][j] = 2;                }            }            else            {                dp[d] = new Dictionary<int, int>();                dp[d][j] = 2;            }            res = Math.Max(res, dp[d][j]);        }    }      // Return res    return res;}   // Driver Codepublic static void Main(string[] args){       // Given array arr[]    int []arr = { 20, 1, 15, 3, 10, 5, 8 };      int N = arr.Length;      // Function call    Console.Write(lenghtOfLongestAP(arr, N));}} // This code is contributed by rutvik_56
<script> // JavaScript program for the above approach // Function that finds the longest// arithmetic subsequence having the// same absolute differencefunction lenghtOfLongestAP(A, n){     // Stores the length of sequences    // having same difference    var dp = new Map();     // Stores the resultant length    var res = 2;     // Iterate over the array    for (var i = 0; i < n; ++i) {         for (var j = i + 1; j < n; ++j) {             var d = A[j] - A[i];              // Update length of subsequence             if (dp.has(d))            {                 if (dp.get(d).has(i))                {                    var tmp = dp.get(d);                    tmp.set(j, dp.get(d).get(i)+1);                }                else                {                    var tmp = new Map();                    tmp.set(j, 2);                    dp.set(d, tmp);                }            }            else            {                var tmp = new Map();                tmp.set(j, 2);                dp.set(d, tmp);            }            res = Math.max(res, dp.get(d).get(j));        }    }     // Return res    return res;} // Driver Code // Given array arr[]var arr = [20, 1, 15, 3, 10, 5, 8];var N = arr.length; // Function Calldocument.write( lenghtOfLongestAP(arr, N)); </script>
  
4
 
 
Time Complexity: O(N2)Auxiliary Space: O(N2)
 
rutvik_56
jithin
divyeshrabadiya07
rrrtnx
arithmetic progression
subsequence
Arrays
Dynamic Programming
Mathematical
Searching
Arrays
Searching
Dynamic Programming
Mathematical
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.