Given a string s, the task is to find the number of possible non-empty sequences of letters that can be made.
Examples:
Input: "AAB" Output: 8 Explanation: 1) A 2) AA 3) AAB 4) AB 5) ABA 6) B 7) BA 8) BAA Total 8 possibilities Input: "AAABBC" Output: 188
Approach: There are two possibilities either take the current character to our answer or leave it. We can solve this problem
To check for duplicates we can take set as a data Structure and will put our answers there and our count will be the size of our set.
Below is the implementation of the above approach:
// C++ program for // the above approach #include <bits/stdc++.h> using namespace std;
// Recursive function which will // calculate all the possibilities // recursively void recur(string& tiles, vector< bool > vis, string ans,
set<string>& se)
{ if (ans.size() > 0) {
// Check that the string
// is already there or not
if (se.count(ans))
return ;
// Else put in set
se.insert(ans);
}
// Run for all the
// possibilities
for ( int i = 0; i < tiles.size(); i++) {
// If already taken
// then don't do anything
if (vis[i])
continue ;
vis[i] = true ;
// Else take it and
// call recur function
recur(tiles, vis, ans + tiles[i], se);
vis[i] = false ;
}
} // Driver code int main()
{ string s = "AAABBC" ;
string curr = "" ;
set<string> se;
vector< bool > vis(s.size(), false );
recur(s, vis, curr, se);
int ans = se.size();
cout << ans << '\n' ;
// uncomment following to print all generated strings
/*
for(auto i: se)
cout<<i<<endl;
*/
return 0;
} |
// Java program for the above approach import java.util.*;
public class Main
{ static HashSet<String> se = new HashSet<String>();
static String tiles;
// Recursive function which will
// calculate all the possibilities
// recursively
static void recur(Vector<Boolean> vis, String ans)
{
// Check that the string
// is already there or not
if (ans.length()> 0 )
{
if (se.contains(ans))
{
return ;
}
// Else put in set
se.add(ans);
}
// Run for all the
// possibilities
for ( int i = 0 ; i < tiles.length(); i++)
{
// If already taken
// then don't do anything
if (vis.get(i))
continue ;
vis.set(i, true );
// Else take it and
//call recur function
recur(vis, ans + tiles.charAt(i));
vis.set(i, false );
}
}
public static void main(String[] args)
{
tiles = "AAABBC" ;
String curr = "" ;
Vector<Boolean> vis = new Vector<Boolean>();
for ( int i = 0 ; i < tiles.length(); i++)
{
vis.add( false );
}
recur(vis, curr);
System.out.print(se.size());
}
} // This code is contributed by rameshtravel07. |
# Python3 program for # the above approach # Recursive function which will # calculate all the possibilities # recursively def recur(vis, ans):
global tiles, se
if ( len (ans) > 0 ):
# Check that the string
# is already there or not
if (ans in se):
return
# Else put in set
se[ans] = 1
# Run for all the
# possibilities
for i in range ( len (tiles)):
# If already taken
# then don't do anything
if (vis[i]):
continue
vis[i] = True
# Else take it and
# call recur function
recur(vis, ans + tiles[i])
vis[i] = False
# Driver code tiles = "AAABBC"
curr = ""
se = dict ()
vis = [ False ] * ( len (tiles))
recur(vis, curr) print ( len (se))
# This code is contributed by mohit kumar 29 |
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG {
static HashSet< string > se = new HashSet< string >();
static string tiles;
// Recursive function which will
// calculate all the possibilities
// recursively
static void recur(List< bool > vis, string ans)
{
// Check that the string
// is already there or not
if (ans.Length>0)
{
if (se.Contains(ans))
{
return ;
}
// Else put in set
se.Add(ans);
}
// Run for all the
// possibilities
for ( int i = 0; i < tiles.Length; i++)
{
// If already taken
// then don't do anything
if (vis[i])
continue ;
vis[i] = true ;
// Else take it and
//call recur function
recur(vis, ans + tiles[i]);
vis[i] = false ;
}
}
static void Main() {
tiles = "AAABBC" ;
string curr = "" ;
List< bool > vis = new List< bool >();
for ( int i = 0; i < tiles.Length; i++)
{
vis.Add( false );
}
recur(vis, curr);
Console.WriteLine(se.Count);
}
} // This code is contributed by divyesh072019. |
<script> // Javascript program for // the above approach // Recursive function which will // calculate all the possibilities // recursively function recur(vis, ans)
{ // Check that the string
// is already there or not
if (ans.length>0)
{
if (se.has(ans))
{
return ;
}
// Else put in set
se.add(ans);
}
// Run for all the
// possibilities
for (let i=0;i<tiles.length;i++)
{
// If already taken
// then don't do anything
if (vis[i])
continue ;
vis[i] = true ;
// Else take it and
//call recur function
recur(vis, ans + tiles[i]);
vis[i] = false ;
}
} // Driver code let tiles = "AAABBC" ;
let curr = "" ;
let se = new Set();
let vis = new Array(tiles.length);
for (let i = 0; i < tiles.length; i++)
{ vis[i] = false ;
} recur(vis, curr); document.write(se.size); // This code is contributed by ab2127 </script> |
188
Time complexity: O(n! * log n)
Auxiliary Space: O(n!)
Another Approach: The idea is to maintain the frequency of the characters of the string and then by choosing each character of the string increment the count by one and decrement the frequency and Recursively call for the rest of the frequencies of the characters.
Below is the implementation of the above approach:
// C++ implementation of the // above approach #include <bits/stdc++.h> using namespace std;
// Function to find the count // of the number of strings void countNumberOfStringsUtil(
vector< int >& freq, int & count)
{ // Loop to iterate over the
// frequency of character of string
for ( int i = 0; i < 26; i++) {
if (freq[i] > 0) {
// reduce the frequency of
// current element
freq[i]--;
count++;
// recursive call
countNumberOfStringsUtil(freq,count);
freq[i]++; // backtrack
}
}
} // Function to count the number of // non-empty sequences int countNumberOfStrings(string s) {
// store the frequency of each character
vector< int > freq(26, 0);
// Maintain the frequency
for ( int i = 0; i < s.size(); i++) {
freq[s[i] - 'A' ]++;
}
int count = 0;
countNumberOfStringsUtil(freq, count);
return count;
} // Driver Code int main()
{ string s = "AAABBC" ;
// Function Call
cout << countNumberOfStrings(s);
return 0;
} |
// Java implementation of the // above approach import java.io.*;
import java.util.*;
class GFG
{ public static int count = 0 ;
// Function to find the count
// of the number of strings
public static void countNumberOfStringsUtil( int [] freq)
{
// Loop to iterate over the
// frequency of character of string
for ( int i = 0 ; i < 26 ; i++)
{
if (freq[i] > 0 )
{
// reduce the frequency of
// current element
freq[i]--;
count++;
// recursive call
countNumberOfStringsUtil(freq);
freq[i]++; // backtrack
}
}
}
// Function to count the number of
// non-empty sequences
public static int countNumberOfStrings(String s)
{
// store the frequency of each character
int [] freq = new int [ 26 ];
Arrays.fill(freq, 0 );
// Maintain the frequency
for ( int i = 0 ; i < s.length(); i++)
{
freq[s.charAt(i) - 'A' ]++;
}
countNumberOfStringsUtil(freq);
return count;
}
// Driver Code
public static void main (String[] args)
{
String s = "AAABBC" ;
// Function Call
System.out.println(countNumberOfStrings(s));
}
} // This code is contributed by rag2127 |
# Python3 implementation of the # above approach count = 0
# Function to find the count # of the number of strings def countNumberOfStringsUtil(freq,
Count):
global count
count = Count
# Loop to iterate over the
# frequency of character of string
for i in range ( 26 ):
if (freq[i] > 0 ):
# Reduce the frequency of
# current element
freq[i] - = 1
count + = 1
# Recursive call
countNumberOfStringsUtil(freq,
count);
# Backtrack
freq[i] + = 1
# Function to count the number of # non-empty sequences def countNumberOfStrings(s):
global count
global freq
# store the frequency
# of each character
freq = [ 0 for i in range ( 26 )]
# Maintain the frequency
for i in range ( len (s)):
freq[ ord (s[i]) -
ord ( 'A' )] + = 1
countNumberOfStringsUtil(freq,
count);
return count
# Driver Code s = "AAABBC"
# Function Call print (countNumberOfStrings(s))
# This code is contributed by avanitrachhadiya2155 |
// C# implementation of the // above approach using System;
using System.Collections.Generic;
class GFG {
static int count = 0;
// Function to find the count
// of the number of strings
static void countNumberOfStringsUtil( int [] freq)
{
// Loop to iterate over the
// frequency of character of string
for ( int i = 0; i < 26; i++)
{
if (freq[i] > 0)
{
// reduce the frequency of
// current element
freq[i]--;
count++;
// recursive call
countNumberOfStringsUtil(freq);
freq[i]++; // backtrack
}
}
}
// Function to count the number of
// non-empty sequences
public static int countNumberOfStrings( string s)
{
// store the frequency of each character
int [] freq = new int [26];
Array.Fill(freq, 0);
// Maintain the frequency
for ( int i = 0; i < s.Length; i++)
{
freq[s[i] - 'A' ]++;
}
countNumberOfStringsUtil(freq);
return count;
}
static void Main() {
string s = "AAABBC" ;
// Function Call
Console.Write(countNumberOfStrings(s));
}
} // This code is contributed by suresh07. |
<script> // Javascript implementation of the // above approach let count = 0; // Function to find the count // of the number of strings
function countNumberOfStringsUtil(freq)
{ // Loop to iterate over the
// frequency of character of string
for (let i = 0; i < 26; i++)
{
if (freq[i] > 0)
{
// reduce the frequency of
// current element
freq[i]--;
count++;
// recursive call
countNumberOfStringsUtil(freq);
freq[i]++; // backtrack
}
}
} // Function to count the number of // non-empty sequences
function countNumberOfStrings(s)
{ // store the frequency of each character
let freq = new Array(26);
for (let i = 0; i < freq.length; i++)
{
freq[i] = 0;
}
// Maintain the frequency
for (let i = 0; i < s.length; i++)
{
freq[s[i].charCodeAt(0) - 'A' .charCodeAt(0)]++;
}
countNumberOfStringsUtil(freq);
return count;
} // Driver Code let s = "AAABBC" ;
// Function Call document.write(countNumberOfStrings(s)); // This code is contributed by unknown2108 </script> |
188
Time complexity: O(n! * 26^n)
Auxiliary Space: O(n)