Count Distinct Subsequences

Last Updated : 6 Dec, 2025

Given a string str, Find the number of distinct subsequences that can be formed from it.
A subsequence is a sequence derived from the original string by deleting zero or more characters without changing the relative order of the remaining characters.

Note: Answer can be very large, so, ouput will be answer modulo 109+7.

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"

Try It Yourself
redirect icon

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

The idea is to generate every possible subsequence of the string and store them in a HashSet to ensure uniqueness. To do this, we apply recursion on each index of the string. For every character at index i, we have two choices:

  • Include str[i]: Add the current character to the subsequence being built and move to the next index.
  • Exclude str[i]: Skip the current character and move to the next index.

The recursion stops when we reach the end of the string, meaning no more characters are left to process. At that point, we insert the generated subsequence into the HashSet.

C++
//Driver Code Starts
#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;

//Driver Code Ends

const int mod = 1e9+7;

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();
}

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

    // to store current subsequence
    string cur;

    generateSubseq(0, cur, str, s);

    int ans = (int)s.size();
    return ans % mod;
}

//Driver Code Starts

int main() {
    string str = "gfg";
    cout << distinctSubseq(str);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.HashSet;

class GFG {

//Driver Code Ends

    static final int mod = 1000000007;

    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);
    }

    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);

        int ans = s.size();
        return ans % mod;
    }

//Driver Code Starts

    public static void main(String[] args) {
        String str = "gfg";
        System.out.println(distinctSubseq(str));
    }
}

//Driver Code Ends
Python
mod = 1000000007

def generateSubseq(ind, cur, s, st):
    n = len(s)

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

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

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


def distinctSubseq(s):

    # to store the unique subsequences
    st = set()

    # to store current subsequence
    cur = ""

    generateSubseq(0, cur, s, st)

    ans = len(st)
    return ans % mod


#Driver Code Starts

if __name__ == "__main__":
    s = "gfg"
    print(distinctSubseq(s))

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Text;        
using System.Collections.Generic;   

class GFG {
//Driver Code Ends

    static int mod = 1000000007;

    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[ind]);
        generateSubseq(ind + 1, cur, str, s);

        // remove the added character
        cur.Remove(cur.Length - 1, 1);
    }

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

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

        generateSubseq(0, cur, str, s);

        int ans = s.Count;
        return ans % mod;
    }

//Driver Code Starts

    public static void Main()
    {
        string str = "gfg";
        Console.WriteLine(distinctSubseq(str));
    }
}

//Driver Code Ends
JavaScript
const mod = 1000000007;

function generateSubseq(ind, cur, str, set) {
    let n = str.length;

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

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

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

function distinctSubseq(str) {

    // to store the unique subsequences
    let set = new Set();

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

    generateSubseq(0, cur, str, set);

    let ans = set.size;
    return ans % mod;
}


//Driver Code Starts

// Driver code
let str = "gfg";
console.log(distinctSubseq(str));

//Driver Code Ends

Output
7

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

The idea is to use dynamic programming (DP) to efficiently count all distinct subsequences while avoiding duplicates caused by repeating characters.

We use a DP array dp[i] where each element stores the number of distinct subsequences for the first i characters, with dp[0] = 1 for the empty subsequence. For each character, subsequences can either include or exclude it, so the total doubles. To avoid counting duplicates when a character repeats, we track its last occurrence in a last[] array and subtract the subsequences counted up to its previous occurrence. This ensures all subsequences are counted exactly once.

By iteratively updating the DP array and the last occurrence array for every character, we ensure that each subsequence is counted exactly once. At the end, dp[n] contains the total number of distinct subsequences.

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <string>
using namespace std;

//Driver Code Ends

int distinctSubseq(string &str) {
    int n = str.size();
    int mod = 1000000007;

    // 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]) % mod;

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

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

//Driver Code Starts

int main() {
    string str = "gfg";
    cout << distinctSubseq(str);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;

class GFG {

//Driver Code Ends

    static int distinctSubseq(String str) {
        int n = str.length();
        int mod = 1000000007;

        // to store the results up to
        // each index i, from 0 to n
        int[] dp = new int[n + 1];
        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]) % mod;

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

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

//Driver Code Starts

    public static void main(String[] args) {
        String str = "gfg";
        System.out.println(distinctSubseq(str));
    }
}

//Driver Code Ends
Python
mod = 1000000007

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]) % mod

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

        # update the last occurrence of the character
        last[idx] = i - 1

    return dp[n]

    
#Driver Code Starts
    
if __name__ == "__main__":
    str = "gfg"
    print(distinctSubseq(str))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG {
    
//Driver Code Ends

    static int distinctSubseq(string str) {
        int n = str.Length;
        int mod = 1000000007;

        // to store the results up to
        // each index i, from 0 to n
        int[] dp = new int[n + 1];
        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] = (int)((2L * dp[i - 1]) % mod);

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

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

//Driver Code Starts

    static void Main() {
        string str = "gfg";
        Console.WriteLine(distinctSubseq(str));
    }
}

//Driver Code Ends
JavaScript
function distinctSubseq(str) {
    let n = str.length;
    const mod = 1000000007;

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

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

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

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

        // update the last occurrence of the character
        last[idx] = i - 1;
    }

    return dp[n];
}


//Driver Code Starts

// Driver Code
let str = "gfg";
console.log(distinctSubseq(str));

//Driver Code Ends

Output
7

[Space Optimized] - 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++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <string>
using namespace std;

//Driver Code Ends

int distinctSubseq(string &str) {
    int n = str.size();
    int mod = 1000000007;

    // 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 = ( (2LL * res) % mod - last[str[i - 1] - 'a'] + mod ) % mod;

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

//Driver Code Starts

int main() {
    string str = "gfg";
    cout << distinctSubseq(str);
    return 0;
}

//Driver Code Ends
Java
//Driver Code Starts
class GfG {

//Driver Code Ends

    static int distinctSubseq(String str) {
        int n = str.length();
        int mod = 1000000007;

        // to store the last occurrence 
        // of each character in the string
        int[] last = new int[26];

        // 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 = (int)(((2L * res) % mod - 
                    last[str.charAt(i - 1) - 'a'] + mod) % mod);

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

//Driver Code Starts

    public static void main(String[] args) {
        String str = "gfg";
        System.out.println(distinctSubseq(str));
    }
}

//Driver Code Ends
Python
def distinctSubseq(s):
    n = len(s)
    MOD = 10**9 + 7

    # 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
        idx = ord(s[i - 1]) - ord('a')
        cur = (2 * res - last[idx]) % MOD

        # update the last occurrence of the character
        last[idx] = res
        res = cur

    return res


#Driver Code Starts

if __name__ == "__main__":
    s = "gfg"
    print(distinctSubseq(s))

#Driver Code Ends
C#
//Driver Code Starts
using System;

class GFG
{
//Driver Code Ends

    static int distinctSubseq(string str)
    {
        int n = str.Length;
        const int MOD = 1000000007;

        // to store the last occurrence 
        // of each character in the string
        int[] last = new int[26];

        // 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 idx = str[i - 1] - 'a';
            int cur = ((2 * res - last[idx]) % MOD + MOD) % MOD;

            // update the last occurrence of the character
            last[idx] = res;
            res = cur;
        }
        return res;
    }

//Driver Code Starts

    static void Main()
    {
        string str = "gfg";
        Console.WriteLine(distinctSubseq(str));
    }
}

//Driver Code Ends
JavaScript
function distinctSubseq(str) {
    const n = str.length;
    const MOD = 1e9 + 7;

    // to store the last occurrence 
    // of each character in the string
    const 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
        const idx = str.charCodeAt(i - 1) - 97;
        let cur = ((2 * res - last[idx]) % MOD + MOD) % MOD;

        // update the last occurrence of the character
        last[idx] = res;
        res = cur;
    }

    return res;
}


//Driver Code Starts
// Driver Code
const str = "gfg";
console.log(distinctSubseq(str));

//Driver Code Ends

Output
7


Comment