Open In App

Count lexicographically smallest subsequences after rearrangement

Last Updated : 06 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S of length N, then your task is to find number of subsequences Y of string S such that:

  • Y must be non-empty string and Y must be lexicographically smallest among all the possible strings obtained by rearranging the characters of Y.

Examples:

Input: N = 2, S = “ju”
Output: 3
Explanation: Three possible strings can be: {“j”, “u”, “ju”}.

Input: N = 3, S = “aba”
Output: 5
Explanation: The five possible strings are: {“a”, “b”, “aa”, “ab”, “aba”}.

Approach: To solve the problem, follow the below idea:

The main idea is to determine the number of ways to form subsets from a given string of characters, consider the frequency of each unique character in S. Let us take an example, in S = “aabbcd”, the frequencies of a, b, c and d are 2, 2, 1 and 1 respectively. To find the ways each character can be represented in a subset, include the character itself, its repetitions, and an empty subset (denoted by {}). This is done by adding 1 to the frequency of each character.

To construct Y, we can run a loop from lexicographically smallest to greatest character present in the string, and for each character ch: if it occurs for cnt times in string S, then we can choose to have (0 or 1 or 2 … or cnt) number of ch in Y. So we have (cnt + 1) choices. Now, we can calculate this for every character and take their product to get the final answer.

Step-by-step algorithm:

  • Create a HashMap let say Map to count the frequency of each distinct character.
  • Create a variable let say Total to count the possible strings Y, initialize it as 1.
  • Run a loop and initialize the frequency of each character of S into Map.
  • Iterate on Map and follow below-mentioned steps under the scope of loop:
    • Total*= (F + 1), where F is the frequency of current character
    • Total%=mod
  • Return (Total – 1).

Below is the implementation of the above approach:

C++




#include <iostream>
#include <string>
#include <unordered_map>
 
// Mod to stop the overflow of integer
const int mod = 1e9 + 7;
 
// Method to output the count of Y strings
void TotalStrings(int N, const std::string& S) {
    // HashMap to count frequency of unique characters
    std::unordered_map<char, int> map;
 
    // Variable to count total number of Y strings
    long long total = 1;
 
    // Initializing frequencies of characters in map
    for (int i = 0; i < N; i++) {
        char ch = S[i];
        map[ch]++;
    }
 
    // Iterating over Map and counting Y strings
    for (const auto& pair : map) {
        total *= (pair.second + 1);
        total %= mod;
    }
 
    // Printing output
    std::cout << (total - 1 + mod) % mod << std::endl;  // Ensure the value is non-negative
}
 
// Driver Function
int main() {
    // Input
    int N = 3;
    std::string S = "aba";
 
    // Function_call
    TotalStrings(N, S);
 
    return 0;
}
 
// This code is contributed by shivamgupta0987654321


Java




import java.util.*;
 
// Driver Class
public class Main {
    // Mod to stop the overflow of integer
    static int mod = (int)Math.pow(10, 9) + 7;
 
    // Driver Function
    public static void main(String[] args)
    {
 
        // Input
        int N = 3;
        String S = "aba";
 
        // Function_call
        TotalStrings(N, S);
    }
 
    // Method to output the count of Y strings
    public static void TotalStrings(int N, String S)
    {
        // HashMap to count frequency of unique characters
        HashMap<Character, Integer> map = new HashMap<>();
 
        // Variable to count total number of Y strings
        long total = 1;
 
        // Initializing frequencies of characters in map
        for (int i = 0; i < N; i++) {
            char ch = S.charAt(i);
            map.put(ch, map.getOrDefault(ch, 0) + 1);
        }
 
        // Iterating over Map and counting Y strings
        for (Map.Entry<Character, Integer> set :
            map.entrySet()) {
            total *= (set.getValue() + 1);
            total %= mod;
        }
 
        // Printing output
        System.out.println(total - 1);
    }
}


Python3




# Method to output the count of Y strings
def total_strings(N, S):
    # HashMap to count frequency of unique characters
    char_freq_map = {}
 
    # Variable to count total number of Y strings
    total = 1
 
    # Initializing frequencies of characters in map
    for i in range(N):
        ch = S[i]
        char_freq_map[ch] = char_freq_map.get(ch, 0) + 1
 
    # Iterating over Map and counting Y strings
    for freq in char_freq_map.values():
        total *= (freq + 1)
        total %= (10**9 + 7)
 
    # Printing output
    print((total - 1 + (10**9 + 7)) % (10**9 + 7))  # Ensure the value is non-negative
 
 
# Driver Function
def main():
    # Input
    N = 3
    S = "aba"
 
    # Function call
    total_strings(N, S)
 
 
# Entry point of the program
if __name__ == "__main__":
    main()


C#




using System;
using System.Collections.Generic;
 
class GFG
{
    // Mod to stop the overflow of integer
    static int mod = (int)Math.Pow(10, 9) + 7;
 
    // Driver Function
    public static void Main(string[] args)
    {
        // Input
        int N = 3;
        string S = "aba";
 
        // Function call
        TotalStrings(N, S);
    }
 
    // Method to output the count of Y strings
    public static void TotalStrings(int N, string S)
    {
        // Dictionary to count frequency of unique characters
        Dictionary<char, int> map = new Dictionary<char, int>();
 
        // Variable to count total number of Y strings
        long total = 1;
 
        // Initializing frequencies of characters in map
        for (int i = 0; i < N; i++)
        {
            char ch = S[i];
            if (map.ContainsKey(ch))
                map[ch]++;
            else
                map[ch] = 1;
        }
 
        // Iterating over Dictionary and counting Y strings
        foreach (var pair in map)
        {
            total *= (pair.Value + 1);
            total %= mod;
        }
 
        // Printing output
        Console.WriteLine(total - 1);
    }
}


Javascript




// Method to output the count of Y strings
function totalStrings(N, S) {
    // Map to count frequency of unique characters
    let map = new Map();
 
    // Variable to count total number of Y strings
    let total = 1;
 
    // Initializing frequencies of characters in map
    for (let i = 0; i < N; i++) {
        let ch = S[i];
        if (map.has(ch)) {
            map.set(ch, map.get(ch) + 1);
        } else {
            map.set(ch, 1);
        }
    }
 
    // Iterating over Map and counting Y strings
    map.forEach((value) => {
        total *= (value + 1);
        total %= 1000000007; // Equivalent to mod in C++
    });
 
    // Printing output
    console.log((total - 1 + 1000000007) % 1000000007); // Ensure the value is non-negative
}
 
// Driver Function
function main() {
    // Input
    let N = 3;
    let S = "aba";
 
    // Function call
    totalStrings(N, S);
}
 
// Invoke main function
main();
//This code is contributed by Utkarsh


Output

5



Time Complexity: O(N), where N is the size of the input string S.
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads