Open In App

Count Distinct Subsequences

Last Updated : 13 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string str of length n, your task is to find the count of distinct subsequences of it.

Examples: 

Input: str = "gfg"
Output: 7
Explanation: The seven distinct subsequences are "", "g", "f", "gf", "fg", "gg" and "gfg"

Input: str = "ggg"
Output: 4
Explanation: The four distinct subsequences are "", "g", "gg" and "ggg"

[Naive Approach] - Generating All Subsequences - O(2 ^ n) Time and O(2 ^ n) Space

The problem of counting distinct subsequences is easy if all characters of input string are distinct. The count is equal to nC0 + nC1 + nC2 + … nCn = 2n.
How to count distinct subsequences when there can be repetition in input string? 

The idea is to generate all possible subsequences of the given string str, and store them in a HashSet to find the count of distinct subsequences. To do so, create a HashSet to store the subsequences, and call a recursive function for all the indices of the string, starting from the 0th index. For each index i, there are two possibilities:

  • Include str[i]: Add the character str[i] in subsequence and move to next one.
  • Not Include str[i]: Skip the character str[i], and move to the next one.

At last, if i == n, store the subsequence in the HashSet. The size of the HashSet is the required result.

Below is given the implementation:

C++
#include <bits/stdc++.h>
using namespace std;

// recursive function to generate all
// possible subsequences of the string
void generateSubseq(int ind, string &cur, 
    string &str, unordered_set<string> &s) {
    int n = str.size();

    // if the end of string is reached
    // store the subsequence in set
    if(ind == n) {
        s.insert(cur); 
        return;
    }

    // skip the current character
    generateSubseq(ind + 1, cur, str, s);

    // add the character str[i]
    cur.push_back(str[ind]);
    generateSubseq(ind + 1, cur, str, s);

    // remove the added character
    cur.pop_back();
}

// to find the count of unique subsequences
int distinctSubseq(string &str) {
    
    // to store the unique subsequences
    unordered_set<string> s;

    // to store current subsequence
    string cur;

    generateSubseq(0, cur, str, s);

    return s.size();
}

int main() {
    string str = "gfg";
    cout << distinctSubseq(str);
    return 0;
}
Java
import java.util.*;

public class GfG {

    // recursive function to generate all
    // possible subsequences of the string
    static void generateSubseq(int ind, 
    StringBuilder cur, String str, HashSet<String> s) {
        int n = str.length();

        // if the end of string is reached
        // store the subsequence in set
        if (ind == n) {
            s.add(cur.toString());
            return;
        }

        // skip the current character
        generateSubseq(ind + 1, cur, str, s);

        // add the character str[i]
        cur.append(str.charAt(ind));
        generateSubseq(ind + 1, cur, str, s);

        // remove the added character
        cur.deleteCharAt(cur.length() - 1);
    }

    // to find the count of unique subsequences
    static int distinctSubseq(String str) {
    
        // to store the unique subsequences
        HashSet<String> s = new HashSet<>();

        // to store current subsequence
        StringBuilder cur = new StringBuilder();

        generateSubseq(0, cur, str, s);

        return s.size();
    }

    public static void main(String[] args) {
        String str = "gfg";
        System.out.println(distinctSubseq(str));
    }
}
Python
# recursive function to generate all
# possible subsequences of the string
def generateSubseq(ind, cur, str, s):
    n = len(str)

    # if the end of string is reached
    # store the subsequence in set
    if ind == n:
        s.add(cur)
        return

    # skip the current character
    generateSubseq(ind + 1, cur, str, s)

    # add the character str[i]
    cur = cur + str[ind]
    generateSubseq(ind + 1, cur, str, s)

    # remove the added character
    cur = cur[:-1]

# to find the count of unique subsequences
def distinctSubseq(str):
    
    # to store the unique subsequences
    s = set()

    # to store current subsequence
    cur = ""

    generateSubseq(0, cur, str, s)

    return len(s)

if __name__ == "__main__":
    str = "gfg"
    print(distinctSubseq(str))
C#
using System;
using System.Collections.Generic;

public class GfG {

    // recursive function to generate all
    // possible subsequences of the string
    static void generateSubseq(int ind, string cur, 
    string str, HashSet<string> s) {
        int n = str.Length;

        // if the end of string is reached
        // store the subsequence in set
        if (ind == n) {
            s.Add(cur);
            return;
        }

        // skip the current character
        generateSubseq(ind + 1, cur, str, s);

        // add the character str[i]
        cur = cur + str[ind];
        generateSubseq(ind + 1, cur, str, s);

        // remove the added character
        cur = cur.Substring(0, cur.Length - 1);
    }

    // to find the count of unique subsequences
    static int distinctSubseq(string str) {
    
        // to store the unique subsequences
        HashSet<string> s = new HashSet<string>();

        // to store current subsequence
        string cur = "";

        generateSubseq(0, cur, str, s);

        return s.Count;
    }

    public static void Main(string[] args) {
        string str = "gfg";
        Console.WriteLine(distinctSubseq(str));
    }
}
JavaScript
// recursive function to generate all
// possible subsequences of the string
function generateSubseq(ind, cur, str, s) {
    let n = str.length;

    // if the end of string is reached
    // store the subsequence in set
    if (ind === n) {
        s.add(cur);
        return;
    }

    // skip the current character
    generateSubseq(ind + 1, cur, str, s);

    // add the character str[i]
    cur = cur + str.charAt(ind);
    generateSubseq(ind + 1, cur, str, s);

    // remove the added character
    cur = cur.substring(0, cur.length - 1);
}

// to find the count of unique subsequences
function distinctSubseq(str) {
    
    // to store the unique subsequences
    let s = new Set();

    // to store current subsequence
    let cur = "";

    generateSubseq(0, cur, str, s);

    return s.size;
}

function main() {
    let str = "gfg";
    console.log(distinctSubseq(str));
}

main();

Output
7

[Better Approach] - Using Dynamic Programming - O(n) Time and O(n) Space

In the above approach, we generate all the subsequences to find the count of unique ones. Instead of doing so, the idea is to use dynamic programming to store the count of distinct subsequences up to each index i and use it compute the next one. To do so, firstly create an array dp[] of size n.

Let distinctSub(n) be count of subsequences of first n characters in input string. We can
recursively write it as below.
distinctSub(n) = 2*Count(n-1) - Repetition
If current character, i.e., str[n-1] of str has not appeared before, then
Repetition = 0
Else:
Repetition = Count(m)
Here m is index of previous occurrence of current character. We basically remove all
counts ending with previous occurrence of current character.

How does this work? 
If there are no repetitions, then count becomes double of count for n-1 because we get count(n-1) more subsequences by adding current character at the end of all subsequences possible with n-1 length. 
If there are repetitions, then we find a count of all distinct subsequences ending with the previous occurrence. This count can be obtained by recursively calling for an index of the previous occurrence. 
Since the above recurrence has overlapping subproblems, we can solve it using Dynamic Programming.

Follow the below given step-by-step approach:

  • Create an array dp[] of size n + 1, and initialize dp[0] with 1.
  • Also create an array last of size 26, to store the index of last occurrence of each character.
  • Start iterating from index 1 to n, and for each index ind set dp[ind] = dp[ind - 1] * 2 - dp[last(str[i - 1])].
  • Update last[str[i - 1]] to i - 1.
  • At last dp[n] stores the required result.
C++
#include <bits/stdc++.h>
using namespace std;

// to find the count of unique subsequences
int distinctSubseq(string &str) {
    int n = str.size();

    // to store the results up to
    // each index i, from 0 to n
    vector<int> dp(n + 1, 0);
    dp[0] = 1;

    // to store the last occurrence 
    // of each character in the string
    vector<int> last(26, -1);

    for(int i = 1; i <= n; i++) {
        dp[i] = 2 * dp[i - 1];

        // if the character is seen before
        // subtract the count of subsequences
        if(last[str[i - 1] - 'a'] != -1) {
            dp[i] -= dp[last[str[i - 1] - 'a']];
        }

        // update the last occurrence of the character
        last[str[i - 1] - 'a'] = i - 1;
    }
    return dp[n];
}

int main() {
    string str = "gfg";
    cout << distinctSubseq(str);
    return 0;
}
Java
import java.util.*;

public class GfG {

    // to find the count of unique subsequences
    static int distinctSubseq(String str) {
        int n = str.length();

        // to store the results up to
        // each index i, from 0 to n
        int[] dp = new int[n + 1];
        Arrays.fill(dp, 0);
        dp[0] = 1;

        // to store the last occurrence 
        // of each character in the string
        int[] last = new int[26];
        Arrays.fill(last, -1);

        for (int i = 1; i <= n; i++) {
            dp[i] = 2 * dp[i - 1];

            // if the character is seen before
            // subtract the count of subsequences
            if (last[str.charAt(i - 1) - 'a'] != -1) {
                dp[i] -= dp[last[str.charAt(i - 1) - 'a']];
            }

            // update the last occurrence of the character
            last[str.charAt(i - 1) - 'a'] = i - 1;
        }
        return dp[n];
    }

    public static void main(String[] args) {
        String str = "gfg";
        System.out.println(distinctSubseq(str));
    }
}
Python
# to find the count of unique subsequences
def distinctSubseq(str):
    n = len(str)

    # to store the results up to
    # each index i, from 0 to n
    dp = [0] * (n + 1)
    dp[0] = 1

    # to store the last occurrence 
    # of each character in the string
    last = [-1] * 26

    for i in range(1, n + 1):
        dp[i] = 2 * dp[i - 1]

        # if the character is seen before
        # subtract the count of subsequences
        if last[ord(str[i - 1]) - ord('a')] != -1:
            dp[i] -= dp[last[ord(str[i - 1]) - ord('a')]]

        # update the last occurrence of the character
        last[ord(str[i - 1]) - ord('a')] = i - 1
    return dp[n]

if __name__ == "__main__":
    str = "gfg"
    print(distinctSubseq(str))
C#
using System;
using System.Linq;

public class GfG {

    // to find the count of unique subsequences
    public static int distinctSubseq(string str) {
        int n = str.Length;

        // to store the results up to
        // each index i, from 0 to n
        int[] dp = new int[n + 1];
        for (int i = 0; i < dp.Length; i++) {
            dp[i] = 0;
        }
        dp[0] = 1;

        // to store the last occurrence 
        // of each character in the string
        int[] last = new int[26];
        for (int i = 0; i < 26; i++) {
            last[i] = -1;
        }

        for (int i = 1; i <= n; i++) {
            dp[i] = 2 * dp[i - 1];

            // if the character is seen before
            // subtract the count of subsequences
            if (last[str[i - 1] - 'a'] != -1) {
                dp[i] -= dp[last[str[i - 1] - 'a']];
            }

            // update the last occurrence of the character
            last[str[i - 1] - 'a'] = i - 1;
        }
        return dp[n];
    }

    public static void Main(string[] args) {
        string str = "gfg";
        Console.WriteLine(distinctSubseq(str));
    }
}
JavaScript
// to find the count of unique subsequences
function distinctSubseq(str) {
    let n = str.length;

    // to store the results up to
    // each index i, from 0 to n
    let dp = new Array(n + 1).fill(0);
    dp[0] = 1;

    // to store the last occurrence 
    // of each character in the string
    let last = new Array(26).fill(-1);

    for (let i = 1; i <= n; i++) {
        dp[i] = 2 * dp[i - 1];

        // if the character is seen before
        // subtract the count of subsequences
        if (last[str.charCodeAt(i - 1) - 'a'.charCodeAt(0)] !== -1) {
            dp[i] -= dp[last[str.charCodeAt(i - 1) - 'a'.charCodeAt(0)]];
        }

        // update the last occurrence of the character
        last[str.charCodeAt(i - 1) - 'a'.charCodeAt(0)] = i - 1;
    }
    return dp[n];
}

function main() {
    let str = "gfg";
    console.log(distinctSubseq(str));
}

main();

Output
7

[Expected Approach] - O(n) Time and O(1) Space

In the above approach, we use an array to store the last occurrence of each character, which is further used to access value stored in array dp[], but instead of doing so we can directly store the result at last of occurrence of each character, thus we will not required an additional array to store the results.

C++
#include <bits/stdc++.h>
using namespace std;

// to find the count of unique subsequences
int distinctSubseq(string &str) {
    int n = str.size();

    // to store the last occurrence 
    // of each character in the string
    vector<int> last(26, 0);

    // to store result after each index
    int res = 1;

    for(int i = 1; i <= n; i++) {

        // double the count of unique subsequences
        // and remove the repetition
        int cur = 2 * res - last[str[i - 1] - 'a'];

        // update the last occurrence of the character
        last[str[i - 1] - 'a'] = res;
        res = cur;
    }
    return res;
}

int main() {
    string str = "gfg";
    cout << distinctSubseq(str);
    return 0;
}
Java
import java.util.*;

public class GfG {

    // to find the count of unique subsequences
    static int distinctSubseq(String str) {
        int n = str.length();

        // to store the last occurrence 
        // of each character in the string
        int[] last = new int[26];
        Arrays.fill(last, 0);

        // to store result after each index
        int res = 1;

        for (int i = 1; i <= n; i++) {

            // double the count of unique subsequences
            // and remove the repetition
            int cur = 2 * res - last[str.charAt(i - 1) - 'a'];

            // update the last occurrence of the character
            last[str.charAt(i - 1) - 'a'] = res;
            res = cur;
        }
        return res;
    }

    public static void main(String[] args) {
        String str = "gfg";
        System.out.println(distinctSubseq(str));
    }
}
Python
# to find the count of unique subsequences
def distinctSubseq(str):
    n = len(str)

    # to store the last occurrence 
    # of each character in the string
    last = [0] * 26

    # to store result after each index
    res = 1

    for i in range(1, n + 1):

        # double the count of unique subsequences
        # and remove the repetition
        cur = 2 * res - last[ord(str[i - 1]) - ord('a')]

        # update the last occurrence of the character
        last[ord(str[i - 1]) - ord('a')] = res
        res = cur
    return res

if __name__ == "__main__":
    str = "gfg"
    print(distinctSubseq(str))
C#
using System;

public class GfG {

    // to find the count of unique subsequences
    public static int distinctSubseq(string str) {
        int n = str.Length;

        // to store the last occurrence 
        // of each character in the string
        int[] last = new int[26];
        for (int i = 0; i < 26; i++) {
            last[i] = 0;
        }

        // to store result after each index
        int res = 1;

        for (int i = 1; i <= n; i++) {

            // double the count of unique subsequences
            // and remove the repetition
            int cur = 2 * res - last[str[i - 1] - 'a'];

            // update the last occurrence of the character
            last[str[i - 1] - 'a'] = res;
            res = cur;
        }
        return res;
    }

    public static void Main(string[] args) {
        string str = "gfg";
        Console.WriteLine(distinctSubseq(str));
    }
}
JavaScript
// to find the count of unique subsequences
function distinctSubseq(str) {
    let n = str.length;

    // to store the last occurrence 
    // of each character in the string
    let last = new Array(26).fill(0);

    // to store result after each index
    let res = 1;

    for (let i = 1; i <= n; i++) {

        // double the count of unique subsequences
        // and remove the repetition
        let cur = 2 * res - 
        last[str.charCodeAt(i - 1) - 'a'.charCodeAt(0)];

        // update the last occurrence of the character
        last[str.charCodeAt(i - 1) - 'a'.charCodeAt(0)] = res;
        res = cur;
    }
    return res;
}

function main() {
    let str = "gfg";
    console.log(distinctSubseq(str));
}

main();

Output
7

Next Article

Similar Reads