Count of AP Subsequences

Last Updated : 23 Jul, 2026

Given an array arr[] of positive integers, count the total number of subsequences that form an Arithmetic Progression (AP). A subsequence is considered an Arithmetic Progression if the difference between every pair of consecutive elements is the same.

Note: An empty subsequence and every single-element subsequence are also considered Arithmetic Progressions.

Examples: 

Input: arr[] = [1, 2, 3]
Output: 8
Explanation: Arithmetic Progression subsequences from the given array are: [], [1], [2], [3], [1, 2], [2, 3], [1, 3], [1, 2, 3].

Input: arr[] = [10, 20]
Output: 4
Explanation: Arithmetic Progression subsequences from the given array are: [], [10], [20], [10, 20].

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(n*2^n) Time and O(n) Space

The idea is to recursively generate all possible subsequences of the array. For each subsequence, check whether it forms an Arithmetic Progression by verifying that the difference between every pair of consecutive elements is the same. If it does, increment the count. Since every element can either be included or excluded, all 2n subsequences are explored.

Recurrence Relation:

Let count(arr, idx, seq) denote the number of AP subsequences formed from elements at index idx onward, given that seq is the subsequence built so far. At each index, arr[idx] is either excluded or included, giving:

count(arr, idx, seq) = count(arr, idx + 1, seq) + count(arr, idx + 1, seq after including arr[idx])

Working of Approach:

  • Start from the first element and recursively decide whether to include or exclude it in the current subsequence.
  • Once all elements have been processed, check whether the formed subsequence is an Arithmetic Progression.
  • If the subsequence is an AP, increment the answer.
  • Return the total count after exploring all possible subsequences.
C++
#include <bits/stdc++.h>
using namespace std;

bool isAP(vector<int>& seq) {
    int n = seq.size();

    if (n <= 2)
        return true;

    int diff = seq[1] - seq[0];

    for (int i = 2; i < n; i++) {
        if (seq[i] - seq[i - 1] != diff)
            return false;
    }

    return true;
}

int count(vector<int>& arr, int idx, vector<int>& seq) {

    // All elements have been processed.
    if (idx == arr.size())
        return isAP(seq);

    // Skip the current element.
    int ans = count(arr, idx + 1, seq);

    // Include the current element.
    seq.push_back(arr[idx]);

    ans += count(arr, idx + 1, seq);

    seq.pop_back();

    return ans;
}

int countAP(vector<int>& arr) {
    vector<int> seq;
    return count(arr, 0, seq);
}

int main() {
    vector<int> arr = {1, 2, 3};

    cout << countAP(arr);

    return 0;
}
Java
import java.util.List;
import java.util.ArrayList;

class GFG {

    static boolean isAP(List<Integer> seq) {
        int n = seq.size();

        if (n <= 2)
            return true;

        int diff = seq.get(1) - seq.get(0);

        for (int i = 2; i < n; i++) {
            if (seq.get(i) - seq.get(i - 1) != diff)
                return false;
        }

        return true;
    }

    static int count(int[] arr, int idx, List<Integer> seq) {

        // All elements have been processed.
        if (idx == arr.length)
            return isAP(seq) ? 1 : 0;

        // Skip the current element.
        int ans = count(arr, idx + 1, seq);

        // Include the current element.
        seq.add(arr[idx]);

        ans += count(arr, idx + 1, seq);

        seq.remove(seq.size() - 1);

        return ans;
    }

    static int countAP(int[] arr) {
        return count(arr, 0, new ArrayList<>());
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};

        System.out.println(countAP(arr));
    }
}
Python
def isAP(seq):
    if len(seq) <= 2:
        return True

    diff = seq[1] - seq[0]

    for i in range(2, len(seq)):
        if seq[i] - seq[i - 1] != diff:
            return False

    return True


def count(arr, idx, seq):

    # All elements have been processed.
    if idx == len(arr):
        return 1 if isAP(seq) else 0

    # Skip the current element.
    ans = count(arr, idx + 1, seq)

    # Include the current element.
    seq.append(arr[idx])

    ans += count(arr, idx + 1, seq)

    seq.pop()

    return ans


def countAP(arr):
    return count(arr, 0, [])


if __name__ == "__main__":
    arr = [1, 2, 3]

    print(countAP(arr))
C#
using System;
using System.Collections.Generic;

class GFG {

    static bool IsAP(List<int> seq) {
        int n = seq.Count;

        if (n <= 2)
            return true;

        int diff = seq[1] - seq[0];

        for (int i = 2; i < n; i++) {
            if (seq[i] - seq[i - 1] != diff)
                return false;
        }

        return true;
    }

    static int count(int[] arr, int idx, List<int> seq) {

        // All elements have been processed.
        if (idx == arr.Length)
            return IsAP(seq) ? 1 : 0;

        // Skip the current element.
        int ans = count(arr, idx + 1, seq);

        // Include the current element.
        seq.Add(arr[idx]);

        ans += count(arr, idx + 1, seq);

        seq.RemoveAt(seq.Count - 1);

        return ans;
    }

    static int countAP(int[] arr) {
        return count(arr, 0, new List<int>());
    }

    static void Main() {
        int[] arr = {1, 2, 3};

        Console.WriteLine(countAP(arr));
    }
}
JavaScript
function isAP(seq) {
    if (seq.length <= 2)
        return true;

    const diff = seq[1] - seq[0];

    for (let i = 2; i < seq.length; i++) {
        if (seq[i] - seq[i - 1] !== diff)
            return false;
    }

    return true;
}

function count(arr, idx, seq) {

    // All elements have been processed.
    if (idx === arr.length)
        return isAP(seq) ? 1 : 0;

    // Skip the current element.
    let ans = count(arr, idx + 1, seq);

    // Include the current element.
    seq.push(arr[idx]);

    ans += count(arr, idx + 1, seq);

    seq.pop();

    return ans;
}

function countAP(arr) {
    return count(arr, 0, []);
}

// Driver Code
const arr = [1, 2, 3];

console.log(countAP(arr));

Output
8

[Expected Approach] DP to Count AP Sequences Ending with Every Index

  • The above recursive solution uses the state (idx, seq), where seq represents the subsequence formed so far.
  • Since an array of size n can have 2^n different subsequences, memoizing the state (idx, seq) or creating a 2D array would still require an exponential number of states.
  • This problem is optimized through state reformulation, rather than by applying memoization or standard tabulation techniques to the recursive solution.
  • The idea is to redefine the DP state. For a fixed common difference, the DP only needs to track the last value of an arithmetic progression, allowing previously computed counts to be aggregated using sum[value].

Since the array values are bounded, for each possible common difference, we maintain the count of AP subsequences ending with every value. For each element, we either start a new AP of length 2 or extend previously formed APs having the same common difference, and accumulate the total count.

Working of Approach:

  • Count the empty subsequence and all single-element subsequences initially, as they are valid APs.
  • Traverse the array from left to right, treating each element as the last element of an AP.
  • For every possible common difference, compute the previous value that should exist to continue the AP.
  • If the previous value is within the valid range, extend all APs ending with that value and difference, and also count the new AP formed by the current pair.
  • Store the updated count for the current value and difference.
  • After processing all elements, return the accumulated count.
C++
#include <bits/stdc++.h>
using namespace std;

int countAP(vector<int>& arr) {
    int n = arr.size();

    int minVal = *min_element(arr.begin(), arr.end());
    int maxVal = *max_element(arr.begin(), arr.end());

    // Empty subsequence and all single-element subsequences.
    int ans = n + 1;

    vector<int> dp(n);
    vector<int> sum(101);

    // Try every possible common difference.
    for (int diff = minVal - maxVal; diff <= maxVal - minVal; diff++) {

        fill(sum.begin(), sum.end(), 0);

        // Count AP subsequences with common difference diff.
        for (int i = 0; i < n; i++) {

            dp[i] = 1;

            int prev = arr[i] - diff;

            // Extend previously formed APs.
            if (prev >= 1 && prev <= 100)
                dp[i] += sum[prev];

            ans += dp[i] - 1;

            sum[arr[i]] += dp[i];
        }
    }

    return ans;
}

int main() {
    vector<int> arr = {1, 2, 3};

    cout << countAP(arr);

    return 0;
}
Java
import java.util.*;

class GFG {

    static int countAP(int[] arr) {
        int n = arr.length;

        int minVal = Arrays.stream(arr).min().getAsInt();
        int maxVal = Arrays.stream(arr).max().getAsInt();

        // Empty subsequence and all single-element subsequences.
        int ans = n + 1;

        int[] dp = new int[n];
        int[] sum = new int[101];

        // Try every possible common difference.
        for (int diff = minVal - maxVal; diff <= maxVal - minVal; diff++) {

            Arrays.fill(sum, 0);

            // Count AP subsequences with common difference diff.
            for (int i = 0; i < n; i++) {

                dp[i] = 1;

                int prev = arr[i] - diff;

                // Extend previously formed APs.
                if (prev >= 1 && prev <= 100)
                    dp[i] += sum[prev];

                ans += dp[i] - 1;

                sum[arr[i]] += dp[i];
            }
        }

        return ans;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3};

        System.out.println(countAP(arr));
    }
}
Python
def countAP(arr):
    n = len(arr)

    minVal = min(arr)
    maxVal = max(arr)

    # Empty subsequence and all single-element subsequences.
    ans = n + 1

    dp = [0] * n
    total = [0] * 101

    # Try every possible common difference.
    for diff in range(minVal - maxVal, maxVal - minVal + 1):

        total = [0] * 101

        # Count AP subsequences with common difference.
        for i in range(n):

            dp[i] = 1

            prev = arr[i] - diff

            # Extend previously formed APs.
            if 1 <= prev <= 100:
                dp[i] += total[prev]

            ans += dp[i] - 1

            total[arr[i]] += dp[i]

    return ans


if __name__ == "__main__":
    arr = [1, 2, 3]

    print(countAP(arr))
C#
using System;

class GFG {

    static int countAP(int[] arr) {
        int n = arr.Length;

        int minVal = int.MaxValue;
        int maxVal = int.MinValue;

        foreach (int val in arr) {
            minVal = Math.Min(minVal, val);
            maxVal = Math.Max(maxVal, val);
        }

        // Empty subsequence and all single-element subsequences.
        int ans = n + 1;

        int[] dp = new int[n];
        int[] total = new int[101];

        // Try every possible common difference.
        for (int diff = minVal - maxVal; diff <= maxVal - minVal; diff++) {

            Array.Fill(total, 0);

            // Count AP subsequences with common difference.
            for (int i = 0; i < n; i++) {

                dp[i] = 1;

                int prev = arr[i] - diff;

                // Extend previously formed APs.
                if (prev >= 1 && prev <= 100)
                    dp[i] += total[prev];

                ans += dp[i] - 1;

                total[arr[i]] += dp[i];
            }
        }

        return ans;
    }

    static void Main() {
        int[] arr = {1, 2, 3};

        Console.WriteLine(countAP(arr));
    }
}
JavaScript
function countAP(arr) {
    const n = arr.length;

    const minVal = Math.min(...arr);
    const maxVal = Math.max(...arr);

    // Empty subsequence and all single-element subsequences.
    let ans = n + 1;

    const dp = new Array(n).fill(0);
    const total = new Array(101).fill(0);

    // Try every possible common difference.
    for (let diff = minVal - maxVal; diff <= maxVal - minVal; diff++) {

        total.fill(0);

        // Count AP subsequences with common difference.
        for (let i = 0; i < n; i++) {

            dp[i] = 1;

            const prev = arr[i] - diff;

            // Extend previously formed APs.
            if (prev >= 1 && prev <= 100)
                dp[i] += total[prev];

            ans += dp[i] - 1;

            total[arr[i]] += dp[i];
        }
    }

    return ans;
}

// Driver Code
const arr = [1, 2, 3];

console.log(countAP(arr));

Output
8

Time Complexity: O(n * (maxVal - minVal)), as for each possible common difference, the array is traversed once to update the DP states.
Space Complexity: O(n + maxVal), as the algorithm uses a DP array of size n and an auxiliary array of size maxVal + 1 to store counts for each value.

Comment