String having more distinct subsequences

Last Updated : 13 Aug, 2026

Given a pair of stringsĀ s1Ā andĀ s2Ā of equal lengths, your task is to find which of the two strings has moreĀ distinct subsequences. If both strings have the same number of distinct subsequences, returnĀ s1.

Examples:

Input: s1 = "gfg", s2 = "ggg"
Output: "gfg"
Explanation: "gfg" have 6 distinct subsequences whereas "ggg" have 3 distinct subsequences.

Input: s1 = "a", s2 = "b"
Output: "a"
Explanation: Both the strings have only 1 distinct subsequence.

Try It Yourself
redirect icon

[Naive Approach] Generates all unique subsequences - O(2^m + 2^n) Time and O(2^m + 2^n) Space

Idea is to generates all unique subsequences of two input strings using recursion and stores them in an unordered set to automatically eliminate duplicates. By comparing the number of unique subsequences in each string, we determine which string is better that is, the one with more unique subsequences. The use of a global set simplifies tracking uniqueness without requiring additional logic.

We use a set to track and count all distinct subsequences of the given string. Below is an illustration demonstrating how the subsequences are generated for the string "gfg".

112

In the end, the set contains only the distinct subsequences of the string 'gfg', such as '', 'g', 'f', 'gf', 'fg', 'gg', and 'gfg'. These represent all the unique combinations that can be formed by either including or excluding each character from the original string.

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

// Global unordered set to store unique subsequences
unordered_set<string> sn;

// Function to generate all unique subsequences
void subsequences(string& s, string op, int i) {
    if (i == s.size()) {
        sn.insert(op);
        return;
    }

    // Include current character
    subsequences(s, op + s[i], i + 1);

    // Exclude current character
    subsequences(s, op, i + 1);
}

// Function to return the string with more unique subsequences
string betterString(string str1, string str2) {
    subsequences(str1, "", 0);
    int a = sn.size();
    sn.clear();

    subsequences(str2, "", 0);
    int b = sn.size();

    return (b > a) ? str2 : str1;
}

int main() {
    string str1 = "gfg";
    string str2 = "ggg";
    cout << betterString(str1, str2);
    return 0;
}
Java
import java.util.HashSet;
import java.util.Set;

class GfG{

    static Set<String> sn = new HashSet<>();

    // Function to generate all unique subsequences
    public static void subsequences(String s, String op, int i){
        
        if (i == s.length()) {
            sn.add(op);
            return;
        }

        // Include current character
        subsequences(s, op + s.charAt(i), i + 1);

        // Exclude current character
        subsequences(s, op, i + 1);
    }

    // Function to return the string with more unique
    // subsequences
    static String betterString(String str1, String str2){
        subsequences(str1, "", 0);
        int a = sn.size();
        sn.clear();

        subsequences(str2, "", 0);
        int b = sn.size();

        return (b > a) ? str2 : str1;
    }
    public static void main(String[] args) {
      
        String str1 = "gfg";
        String str2 = "ggg";
        System.out.println(betterString(str1, str2));
    }
}
Python
# Global set to store unique subsequences
sn = set()

def subsequences(s, op, i):
    if i == len(s):
        # Exclude empty strings
        if op:  
            sn.add(op)
        return

    # Include current character
    subsequences(s, op + s[i], i + 1)

    # Exclude current character
    subsequences(s, op, i + 1)

def betterString(str1, str2):
    global sn
    sn.clear()
    subsequences(str1, "", 0)
    a = len(sn)

    sn.clear()
    subsequences(str2, "", 0)
    b = len(sn)

    return str2 if b > a else str1

if __name__ == "__main__":
    
    str1 = "gfg"
    str2 = "ggg"
    print(betterString(str1, str2))
    
C#
using System;
using System.Collections.Generic;

class GfG {
    // Global unordered set to store unique subsequences
    private static HashSet<string> sn = new HashSet<string>();

    // Function to generate all unique subsequences
    private static void subsequences(string s, string op, int i){
        if (i == s.Length){
            
            sn.Add(op);
            return;
        }

        // Include current character
        subsequences(s, op + s[i], i + 1);

        // Exclude current character
        subsequences(s, op, i + 1);
    }

    // Function to return the string with more unique subsequences
    public static string betterString(string str1, string str2){
        
        subsequences(str1, "", 0);
        int a = sn.Count;
        sn.Clear();

        subsequences(str2, "", 0);
        int b = sn.Count;

        return (b > a) ? str2 : str1;
    }
     static void Main()
    {
        string str1 = "gfg";
        string str2 = "ggg";
        Console.WriteLine(betterString(str1, str2));
    }
}
JavaScript
// Global set to store unique subsequences
const sn = new Set();

// Function to generate all unique subsequences
function subsequences(s, op, i) {
    if (i === s.length) {
        // Exclude empty strings
        if (op !== "") {  
            sn.add(op);
        }
        return;
    }

    // Include current character
    subsequences(s, op + s[i], i + 1);

    // Exclude current character
    subsequences(s, op, i + 1);
}

// Function to return the string with more unique subsequences
function betterString(str1, str2) {
    sn.clear();
    subsequences(str1, "", 0);
    const a = sn.size;

    sn.clear();
    subsequences(str2, "", 0);
    const b = sn.size;

    return b > a ? str2 : str1;
}

// Driver Code
const str1 = "gfg";
const str2 = "ggg";
console.log(betterString(str1, str2));

Output
gfg

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

Idea is to use dynamic programming to efficiently count the number of distinct subsequences in each string, avoiding the exponential complexity of generating them explicitly. By tracking the last occurrence of each character, it ensures that duplicate subsequences caused by repeated characters are subtracted correctly.

Illustration:

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

// Function to count distinct subsequences using Dynamic Programming
int countSub(string s) {
    // To track last occurrence of each character
    vector<int> last(26, -1); 
    int n = s.length();
    
    // dp[i] stores count of distinct subsequences of length i
    vector<int> dp(n + 1);
    // Empty string has one subsequence: ""
    dp[0] = 1; 

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

        if (last[s[i - 1] - 'a'] != -1)
            dp[i] -= dp[last[s[i - 1] - 'a']];

        last[s[i - 1] - 'a'] = i - 1;
    }

    return dp[n];
}

// Function to return the better string with more distinct subsequences
string betterString(string s1, string s2) {
    int a = countSub(s1);
    int b = countSub(s2);
    return (a < b) ? s2 : s1;
}

int main() {
    string s1 = "gfg";
    string s2 = "ggg";
    cout << betterString(s1, s2);
    return 0;
}
Java
import java.util.*;

public class GfG {

    // Function to count distinct subsequences using Dynamic Programming
    public static int countSub(String s) {
        
        int n = s.length();
        int[] last = new int[26];
        Arrays.fill(last, -1);

        int[] dp = new int[n + 1];
        // Empty string has one subsequence
        dp[0] = 1; 

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

            if (last[s.charAt(i - 1) - 'a'] != -1) {
                dp[i] -= dp[last[s.charAt(i - 1) - 'a']];
            }

            last[s.charAt(i - 1) - 'a'] = i - 1;
        }

        return dp[n];
    }

    // Function to return the better string with more distinct subsequences
    public static String betterString(String s1, String s2) {
        int a = countSub(s1);
        int b = countSub(s2);
        return (a < b) ? s2 : s1;
    }

    public static void main(String[] args) {
        String s1 = "gfg";
        String s2 = "ggg";
        System.out.println(betterString(s1, s2));
    }
}
Python
def countSub(s):
    n = len(s)
    last = [-1] * 26
    dp = [0] * (n + 1)
    
    # Empty string has one subsequence
    dp[0] = 1  
    
    for i in range(1, n + 1):
        dp[i] = 2 * dp[i - 1]

        char_index = ord(s[i - 1])
        if last[char_index - ord('a')] != -1:
            dp[i] -= dp[last[char_index - ord('a')]]

        last[char_index - ord('a')] = i - 1

    return dp[n]

def betterString(s1, s2):
    a = countSub(s1)
    b = countSub(s2)
    return s2 if a < b else s1
    
# Driver Code
if __name__ == "__main__":
    s1 = "gfg"
    s2 = "ggg"
    print(betterString(s1, s2))
C#
using System;
using System.Collections.Generic;

class GfG
{
    // Function to count distinct subsequences using Dynamic Programming
    static int countSub(string s)
    {
        int n = s.Length;
        int[] last = new int[26];
        Array.Fill(last, -1);

        int[] dp = new int[n + 1];
        dp[0] = 1; // Empty string has one subsequence

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

            if (last[s[i - 1] - 'a'] != -1)
                dp[i] -= dp[last[s[i - 1] - 'a']];

            last[s[i - 1] - 'a'] = i - 1;
        }

        return dp[n];
    }

    // Function to return the better string with more distinct subsequences
    static string betterString(string s1, string s2)
    {
        int a = countSub(s1);
        int b = countSub(s2);
        return (a < b) ? s2 : s1;
    }

    static void Main()
    {
        string s1 = "gfg";
        string s2 = "ggg";
        Console.WriteLine(betterString(s1, s2));
    }
}
JavaScript
function countSub(s) {
    let n = s.length;
    let last = new Array(26).fill(-1);
    let dp = new Array(n + 1).fill(0);

    // Empty string has one subsequence
    dp[0] = 1;

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

        let char_index = s.charCodeAt(i - 1);
        if (last[char_index - 'a'.charCodeAt(0)]!= -1) {
            dp[i] -= dp[last[char_index - 'a'.charCodeAt(0)]];
        }

        last[char_index - 'a'.charCodeAt(0)] = i - 1;
    }

    return dp[n];
}

function betterString(s1, s2) {
    let a = countSub(s1);
    let b = countSub(s2);
    return a < b? s2 : s1;
}

// Driver Code
let s1 = "gfg";
let s2 = "ggg";
console.log(betterString(s1, s2));

Output
gfg

[Expected Approach] Space Optimization - 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. Please count the number of distinct subsequences for more details.

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

// to find the count of unique subsequences
int countSub(string &s) {
    int n = s.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[s[i - 1] - 'a'];

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

// Function to return the better string with more distinct subsequences
string betterString(string s1, string s2) {
    int a = countSub(s1);
    int b = countSub(s2);
    return (a < b) ? s2 : s1;
}

int main() {
    string s1 = "gfg";
    string s2 = "ggg";
    cout << betterString(s1, s2);
    return 0;
}
Java
import java.util.*;

public class GfG {

    // Function to count distinct subsequences using Dynamic Programming
    static int countSub(String s) {
        int n = s.length();

        // to store the results up to
        // each index i, from 0 to n
        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[s.charAt(i - 1) - 'a'];

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

    // Function to return the better string with more distinct subsequences
    public static String betterString(String s1, String s2) {
        int a = countSub(s1);
        int b = countSub(s2);
        return (a < b) ? s2 : s1;
    }

    public static void main(String[] args) {
        String s1 = "gfg";
        String s2 = "ggg";
        System.out.println(betterString(s1, s2));
    }
}
Python
def countSub(s):
    n = len(s)

    # 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(s[i - 1]) - ord('a')]

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

def betterString(s1, s2):
    a = countSub(s1)
    b = countSub(s2)
    return s2 if a < b else s1
    
# Driver Code
if __name__ == "__main__":
    s1 = "gfg"
    s2 = "ggg"
    print(betterString(s1, s2))
C#
using System;
using System.Collections.Generic;

class GfG{
    
    // Function to count distinct subsequences using Dynamic Programming
    public static int countSub(string s) {
        int n = s.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[s[i - 1] - 'a'];

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

    // Function to return the better string with more distinct subsequences
    static string betterString(string s1, string s2){
        
        int a = countSub(s1);
        int b = countSub(s2);
        return (a < b) ? s2 : s1;
    }

    static void Main(){
        
        string s1 = "gfg";
        string s2 = "ggg";
        Console.WriteLine(betterString(s1, s2));
    }
}
JavaScript
// to find the count of unique subsequences
function countSub(s) {
    let n = s.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[s.charCodeAt(i - 1) - 'a'.charCodeAt(0)];

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


function betterString(s1, s2) {
    const a = countSub(s1);
    const b = countSub(s2);
    return (a < b) ? s2 : s1;
}

// Example usage
const s1 = "gfg";
const s2 = "ggg";
console.log(betterString(s1, s2));

Output
gfg
Comment