Count lexicographically smallest subsequences after rearrangement
Last Updated :
06 Feb, 2024
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>
const int mod = 1e9 + 7;
void TotalStrings( int N, const std::string& S) {
std::unordered_map< char , int > map;
long long total = 1;
for ( int i = 0; i < N; i++) {
char ch = S[i];
map[ch]++;
}
for ( const auto & pair : map) {
total *= (pair.second + 1);
total %= mod;
}
std::cout << (total - 1 + mod) % mod << std::endl;
}
int main() {
int N = 3;
std::string S = "aba" ;
TotalStrings(N, S);
return 0;
}
|
Java
import java.util.*;
public class Main {
static int mod = ( int )Math.pow( 10 , 9 ) + 7 ;
public static void main(String[] args)
{
int N = 3 ;
String S = "aba";
TotalStrings(N, S);
}
public static void TotalStrings( int N, String S)
{
HashMap<Character, Integer> map = new HashMap<>();
long total = 1 ;
for ( int i = 0 ; i < N; i++) {
char ch = S.charAt(i);
map.put(ch, map.getOrDefault(ch, 0 ) + 1 );
}
for (Map.Entry<Character, Integer> set :
map.entrySet()) {
total *= (set.getValue() + 1 );
total %= mod;
}
System.out.println(total - 1 );
}
}
|
Python3
def total_strings(N, S):
char_freq_map = {}
total = 1
for i in range (N):
ch = S[i]
char_freq_map[ch] = char_freq_map.get(ch, 0 ) + 1
for freq in char_freq_map.values():
total * = (freq + 1 )
total % = ( 10 * * 9 + 7 )
print ((total - 1 + ( 10 * * 9 + 7 )) % ( 10 * * 9 + 7 ))
def main():
N = 3
S = "aba"
total_strings(N, S)
if __name__ = = "__main__" :
main()
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int mod = ( int )Math.Pow(10, 9) + 7;
public static void Main( string [] args)
{
int N = 3;
string S = "aba" ;
TotalStrings(N, S);
}
public static void TotalStrings( int N, string S)
{
Dictionary< char , int > map = new Dictionary< char , int >();
long total = 1;
for ( int i = 0; i < N; i++)
{
char ch = S[i];
if (map.ContainsKey(ch))
map[ch]++;
else
map[ch] = 1;
}
foreach ( var pair in map)
{
total *= (pair.Value + 1);
total %= mod;
}
Console.WriteLine(total - 1);
}
}
|
Javascript
function totalStrings(N, S) {
let map = new Map();
let total = 1;
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);
}
}
map.forEach((value) => {
total *= (value + 1);
total %= 1000000007;
});
console.log((total - 1 + 1000000007) % 1000000007);
}
function main() {
let N = 3;
let S = "aba" ;
totalStrings(N, S);
}
main();
|
Time Complexity: O(N), where N is the size of the input string S.
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...