Open In App

Longest subsequence forming an Arithmetic Progression (AP)

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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: 6
Explanation:
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: 4
Explanation:
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.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
int longestAPSubsequence(int arr[], int n)
{
    int ans = 0; // Initialize the length of the longest
                 // subsequence to 0
    for (int i = 0; i < n - 1;
         i++) { // Loop through all pairs of elements in the
                // array
        for (int j = i + 1; j < n; j++) {
            int diff = arr[j]
                       - arr[i]; // Calculate the difference
                                 // between the two elements
            int len = 2; // Initialize the length of the
                         // current subsequence to 2
            int curr = arr[j]; // Set the current element to
                               // the second element of the
                               // subsequence
            for (int k = j + 1; k < n;
                 k++) { // Loop through the remaining
                        // elements of the array
                if (arr[k] - curr
                    == diff) { // Check if the next element
                               // is part of the subsequence
                    len++; // Increment the length of the
                           // subsequence
                    curr
                        = arr[k]; // Set the current element
                                  // to the next element of
                                  // the subsequence
                }
            }
            ans = max(ans,
                      len); // Update the length of the
                            // longest subsequence if the
                            // current subsequence is longer
        }
    }
    return ans; // Return the length of the longest
                // subsequence
}
 
int main()
{
    int arr[] = {
        20, 1, 15, 3, 10, 5, 8
    }; // Initialize the array
    int n = sizeof(arr)
            / sizeof(
                arr[0]); // Calculate the size of the array
    cout << longestAPSubsequence(arr, n)
         << endl; // Call the function and print the length
                  // of the longest subsequence
    return 0;
}
// This code is contributed by rudra1807raj


Java




public class LongestAPSubsequence {
 
    // Find the length of the longest arithmetic subsequence
    static int longestAPSubsequence(int[] arr, int n) {
        int ans = 0; // Initialize the length of the longest subsequence to 0
         
        // Loop through all pairs of elements in the array
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                int diff = arr[j] - arr[i]; // Calculate the difference between the two elements
                int len = 2; // Initialize the length of the current subsequence to 2
                int curr = arr[j]; // Set the current element to the second element of the subsequence
                 
                // Loop through the remaining elements of the array
                for (int k = j + 1; k < n; k++) {
                    if (arr[k] - curr == diff) { // Check if the next element is part of the subsequence
                        len++; // Increment the length of the subsequence
                        curr = arr[k]; // Set the current element to the next element of the subsequence
                    }
                }
                 
                ans = Math.max(ans, len); // Update the length of the longest subsequence if the current subsequence is longer
            }
        }
         
        return ans; // Return the length of the longest subsequence
    }
 
    public static void main(String[] args) {
        int[] arr = {20, 1, 15, 3, 10, 5, 8}; // Initialize the array
        int n = arr.length; // Calculate the size of the array
         
        // Call the function and print the length of the longest subsequence
        System.out.println(longestAPSubsequence(arr, n));
    }
}


Python3




# Python program for the above approach to find the length of longest AP subsequence
def longestAPSubsequence(arr, n):
    ans = 0 # Initialize the length of the longest subsequence to 0
    for i in range(n - 1): # Loop through all pairs of elements in the array
        for j in range(i + 1, n):
            diff = arr[j] - arr[i] # Calculate the difference between the two elements
            len = 2 # Initialize the length of the current subsequence to 2
            curr = arr[j] # Set the current element to the second element of the subsequence
            for k in range(j + 1, n): # Loop through the remaining elements of the array
                if arr[k] - curr == diff: # Check if the next element is part of the subsequence
                    len += 1 # Increment the length of the subsequence
                    curr = arr[k] # Set the current element to the next element of the subsequence
            ans = max(ans, len) # Update the length of the longest subsequence if the current subsequence is longer
    return ans # Return the length of the longest subsequence
 
arr = [20, 1, 15, 3, 10, 5, 8] # Initialize the array
n = len(arr) # Calculate the size of the array
print(longestAPSubsequence(arr, n)) # Call the function and print the length of the longest subsequence


C#




using System;
 
class Program
{
  static int LongestAPSubsequence(int[] arr, int n)
  {
    int ans = 0; // Initialize the length of the longest
    // subsequence to 0
    for (int i = 0; i < n - 1; i++) // Loop through all pairs of elements in the array
    {
      for (int j = i + 1; j < n; j++)
      {
        int diff = arr[j] - arr[i]; // Calculate the difference between the two elements
        int len = 2; // Initialize the length of the current subsequence to 2
        int curr = arr[j]; // Set the current element to the second element of the subsequence
        for (int k = j + 1; k < n; k++) // Loop through the remaining elements of the array
        {
          if (arr[k] - curr == diff) // Check if the next element is part of the subsequence
          {
            len++; // Increment the length of the subsequence
            curr = arr[k]; // Set the current element to the next element of the subsequence
          }
        }
        ans = Math.Max(ans, len); // Update the length of the longest subsequence if the current subsequence is longer
      }
    }
    return ans; // Return the length of the longest subsequence
  }
 
  static void Main(string[] args)
  {
    int[] arr = { 20, 1, 15, 3, 10, 5, 8 }; // Initialize the array
    int n = arr.Length; // Calculate the size of the array
    Console.WriteLine(LongestAPSubsequence(arr, n)); // Call the function and print the length of the longest subsequence
  }
}
 
// This code is contributed by rudra1807raj


Javascript




function longestAPSubsequence(arr) {
    let ans = 0; // Initialize the length of the longest subsequence to 0
    const n = arr.length;
 
    for (let i = 0; i < n - 1; i++) { // Loop through all pairs of elements in the array
        for (let j = i + 1; j < n; j++) {
            const diff = arr[j] - arr[i]; // Calculate the difference between the two elements
            let len = 2; // Initialize the length of the current subsequence to 2
            let curr = arr[j]; // Set the current element to the second element of the subsequence
 
            for (let k = j + 1; k < n; k++) { // Loop through the remaining elements of the array
                if (arr[k] - curr === diff) { // Check if the next element is part of the subsequence
                    len++; // Increment the length of the subsequence
                    curr = arr[k]; // Set the current element to the next element of the subsequence
                }
            }
            ans = Math.max(ans, len); // Update the length of the longest subsequence if the current subsequence is longer
        }
    }
    return ans; // Return the length of the longest subsequence
}
 
const arr = [20, 1, 15, 3, 10, 5, 8]; // Initialize the array
console.log(longestAPSubsequence(arr)); // Call the function and print the length of the longest subsequence


Output: 

4

Time Complexity: The time complexity of this solution is O(N^3) because of the three nested loops, where N is the size of the input array. 
Auxiliary Space: The space complexity of this solution is O(1) because only a constant amount of extra space is used for storing the loop indices and a few variables.

Efficient Approach: The above approach can be optimized using Dynamic Programming. Below are the steps:

  1. Initialize an auxiliary matrix dp[][] where dp[i][j] denotes the length of subsequence starting at i and having a common difference as j.
  2. 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:
      1. 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.
      2. 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].
  3. Finally, print the maximum length of all subsequences formed.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function that finds the longest
// arithmetic subsequence having the
// same absolute difference
int 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 Code
int 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




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function that finds the longest
// arithmetic subsequence having the
// same absolute difference
static 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 Code
public 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




# Python3 program for the above approach
 
# Function that finds the longest
# arithmetic subsequence having the
# same absolute difference
def 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 Call
print(lenghtOfLongestAP(arr, N))
 
# This code is contributed by divyeshrabadiya07


C#




// C# program for the above approach
using System;
using System.Collections.Generic; 
 
class GFG{
   
// Function that finds the longest
// arithmetic subsequence having the
// same absolute difference
static 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 Code
public 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


Javascript




<script>
 
// JavaScript program for the above approach
 
// Function that finds the longest
// arithmetic subsequence having the
// same absolute difference
function 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 Call
document.write( lenghtOfLongestAP(arr, N));
 
</script>


 
 

Output

4

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

 



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