Longest subsequence forming an Arithmetic Progression (AP)
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;
for ( int i = 0; i < n - 1;
i++) {
for ( int j = i + 1; j < n; j++) {
int diff = arr[j]
- arr[i];
int len = 2;
int curr = arr[j];
for ( int k = j + 1; k < n;
k++) {
if (arr[k] - curr
== diff) {
len++;
curr
= arr[k];
}
}
ans = max(ans,
len);
}
}
return ans;
}
int main()
{
int arr[] = {
20, 1, 15, 3, 10, 5, 8
};
int n = sizeof (arr)
/ sizeof (
arr[0]);
cout << longestAPSubsequence(arr, n)
<< endl;
return 0;
}
|
Java
public class LongestAPSubsequence {
static int longestAPSubsequence( int [] arr, int n) {
int ans = 0 ;
for ( int i = 0 ; i < n - 1 ; i++) {
for ( int j = i + 1 ; j < n; j++) {
int diff = arr[j] - arr[i];
int len = 2 ;
int curr = arr[j];
for ( int k = j + 1 ; k < n; k++) {
if (arr[k] - curr == diff) {
len++;
curr = arr[k];
}
}
ans = Math.max(ans, len);
}
}
return ans;
}
public static void main(String[] args) {
int [] arr = { 20 , 1 , 15 , 3 , 10 , 5 , 8 };
int n = arr.length;
System.out.println(longestAPSubsequence(arr, n));
}
}
|
Python3
def longestAPSubsequence(arr, n):
ans = 0
for i in range (n - 1 ):
for j in range (i + 1 , n):
diff = arr[j] - arr[i]
len = 2
curr = arr[j]
for k in range (j + 1 , n):
if arr[k] - curr = = diff:
len + = 1
curr = arr[k]
ans = max (ans, len )
return ans
arr = [ 20 , 1 , 15 , 3 , 10 , 5 , 8 ]
n = len (arr)
print (longestAPSubsequence(arr, n))
|
C#
using System;
class Program
{
static int LongestAPSubsequence( int [] arr, int n)
{
int ans = 0;
for ( int i = 0; i < n - 1; i++)
{
for ( int j = i + 1; j < n; j++)
{
int diff = arr[j] - arr[i];
int len = 2;
int curr = arr[j];
for ( int k = j + 1; k < n; k++)
{
if (arr[k] - curr == diff)
{
len++;
curr = arr[k];
}
}
ans = Math.Max(ans, len);
}
}
return ans;
}
static void Main( string [] args)
{
int [] arr = { 20, 1, 15, 3, 10, 5, 8 };
int n = arr.Length;
Console.WriteLine(LongestAPSubsequence(arr, n));
}
}
|
Javascript
function longestAPSubsequence(arr) {
let ans = 0;
const n = arr.length;
for (let i = 0; i < n - 1; i++) {
for (let j = i + 1; j < n; j++) {
const diff = arr[j] - arr[i];
let len = 2;
let curr = arr[j];
for (let k = j + 1; k < n; k++) {
if (arr[k] - curr === diff) {
len++;
curr = arr[k];
}
}
ans = Math.max(ans, len);
}
}
return ans;
}
const arr = [20, 1, 15, 3, 10, 5, 8];
console.log(longestAPSubsequence(arr));
|
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:
- 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.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int lenghtOfLongestAP( int A[], int n)
{
unordered_map< int ,
unordered_map< int , int > >
dp;
int res = 2;
for ( int i = 0; i < n; ++i) {
for ( int j = i + 1; j < n; ++j) {
int d = A[j] - A[i];
dp[d][j] = dp[d].count(i)
? dp[d][i] + 1
: 2;
res = max(res, dp[d][j]);
}
}
return res;
}
int main()
{
int arr[] = { 20, 1, 15, 3, 10, 5, 8 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << lenghtOfLongestAP(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static int lenghtOfLongestAP( int A[], int n)
{
Map<Integer,
Map<Integer,
Integer>> dp = new HashMap<Integer,
Map<Integer,
Integer>>();
int res = 2 ;
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;
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;
}
public static void main(String[] args)
{
int arr[] = { 20 , 1 , 15 , 3 , 10 , 5 , 8 };
int N = arr.length;
System.out.println(lenghtOfLongestAP(arr, N));
}
}
|
Python3
def lenghtOfLongestAP(A, n) :
dp = {}
res = 2
for i in range (n) :
for j in range (i + 1 , n) :
d = A[j] - A[i]
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
arr = [ 20 , 1 , 15 , 3 , 10 , 5 , 8 ]
N = len (arr)
print (lenghtOfLongestAP(arr, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int lenghtOfLongestAP( int []A, int n)
{
Dictionary< int ,
Dictionary< int , int >> dp = new Dictionary< int ,
Dictionary< int , int >>();
int res = 2;
for ( int i = 0; i < n; ++i)
{
for ( int j = i + 1; j < n; ++j)
{
int d = A[j] - A[i];
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;
}
public static void Main( string [] args)
{
int []arr = { 20, 1, 15, 3, 10, 5, 8 };
int N = arr.Length;
Console.Write(lenghtOfLongestAP(arr, N));
}
}
|
Javascript
<script>
function lenghtOfLongestAP(A, n)
{
var dp = new Map();
var res = 2;
for ( var i = 0; i < n; ++i) {
for ( var j = i + 1; j < n; ++j) {
var d = A[j] - A[i];
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;
}
var arr = [20, 1, 15, 3, 10, 5, 8];
var N = arr.length;
document.write( lenghtOfLongestAP(arr, N));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Last Updated :
14 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...