Count Distinct Subsequences (original) (raw)

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 **10 9 +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 Yourselfredirect icon

Table of Content

[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:

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 #include #include using namespace std;

//Driver Code Ends

const int mod = 1e9+7;

void generateSubseq(int ind, string &cur, string &str, unordered_set &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

`

[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 #include #include 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

`

[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 #include #include 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

`