Count anagrams having first character as a consonant and no pair of consonants or vowels placed adjacently
Given a string S of length N, the task is to count the number of anagrams of S whose first character is a consonant and no pair of consonants or vowels are adjacent to each other.
Examples:
Input: S = “GADO”
Output: 4
Explanation:
The anagrams of string S satisfying the given conditions are GADO, GODA, DOGA, DAGO.
Therefore, the total number of such anagrams is 4.Input: S = “AABCY”
Output: 6
Explanation:
The anagrams of the string S satisfying the given conditions are BACAY, BAYAC, CABAY, CAYAB, YABAC, YACAB.
Therefore, the total number of such anagrams is 6.
Naive Approach: The simplest approach is to generate all possible anagrams of the given string and count those anagrams that satisfy the given condition. Finally, print the count obtained.
Time Complexity: O(N!*N)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized based on the following observations:
- Strings that have an equal number of consonants and vowels satisfy the given condition.
- Strings having one more consonant than vowel also satisfy the given condition.
- Apart from these two conditions, the count of possible anagrams will always be 0.
- Now, the problem can be solved by using a combinatorial formula. Consider there are C1, C2…, CN consonants and V1, V2, …, VN vowels in the string S and
and \sum C
denote the total number of consonants and vowels respectively, then the answer would be:
where,
Ci is the count of ith consonant.
Vi is the count of ith vowel.
Follow the steps below to solve the problem:
- Initialize a variable, say answer, to store the total count of anagrams.
- Store the frequency of each character of the string S in a HashMap count.
- Store the number of vowels and consonants in S in variables V and C respectively.
- If the value of V is not equal to C or C is not equal to (V + 1), then print 0. Otherwise, performing the following steps:
- Initialize denominator as 1.
- Traverse the string S using the variable i and update the denominator as denominator*((count[S[i]])!).
- Initialize numerator to V!*C!, and update the value of answer as numerator/denominator.
- After completing the above steps, print the value of the answer as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> #define ll long long #define mod 1000000007 #define N 1000001 using namespace std; // Function to compute factorials till N void Precomputefact(unordered_map<ll, ll>& fac) { ll ans = 1; // Iterate in the range [1, N] for (ll i = 1; i <= N; i++) { // Update ans to ans*i ans = (ans * i) % mod; // Store the value of ans // in fac[i] fac[i] = ans; } return ; } // Function to check whether the // current character is a vowel or not bool isVowel( char a) { if (a == 'A' || a == 'E' || a == 'I' || a == 'O' || a == 'U' ) return true ; else return false ; } // Function to count the number of // anagrams of S satisfying the // given condition void countAnagrams(string s, int n) { // Store the factorials upto N unordered_map<ll, ll> fac; // Function Call to generate // all factorials upto n Precomputefact(fac); // Create a hashmap to store // frequencies of all characters unordered_map< char , ll> count; // Store the count of // vowels and consonants int vo = 0, co = 0; // Iterate through all // characters in the string for ( int i = 0; i < n; i++) { // Update the frequency // of current character count[s[i]]++; // Check if the character // is vowel or consonant if (isVowel(s[i])) vo++; else co++; } // Check if ΣC==ΣV+1 or ΣC==ΣV if ((co == vo + 1) || (co == vo)) { // Store the denominator ll deno = 1; // Calculate the denominator // of the expression for ( auto c : count) { // Multiply denominator by factorial // of counts of all letters deno = (deno * fac[c.second]) % mod; } // Store the numerator ll nume = fac[co] % mod; nume = (nume * fac[vo]) % mod; // Store the answer by dividing // numerator by denominator ll ans = nume / deno; // Print the answer cout << ans; } // Otherwise, print 0 else { cout << 0; } } // Driver Code int main() { string S = "GADO" ; int l = S.size(); countAnagrams(S, l); return 0; } |
Java
import java.util.*; class Main { static int mod = 1000000007 ; static int N = 1000001 ; static HashMap<Integer, Long> fac = new HashMap<Integer, Long>(); // Function to compute factorials till N static void precomputeFact() { long ans = 1 ; // Iterate in the range [1, N] for ( int i = 1 ; i <= N; i++) { // Update ans to ans*i ans = (ans * i) % mod; // Store the value of ans in fac[i] fac.put(i, ans); } } // Function to check whether the current character is a // vowel or not static boolean isVowel( char a) { return a == 'A' || a == 'E' || a == 'I' || a == 'O' || a == 'U' ; } // Function to count the number of anagrams of S // satisfying the given condition static void countAnagrams(String s, int n) { // Store the factorials upto N // Function Call to generate all factorials upto n precomputeFact(); // Create a hashmap to store frequencies of all // characters HashMap<Character, Integer> count = new HashMap<>(); // Store the count of vowels and consonants int vo = 0 ; int co = 0 ; // Iterate through all characters in the string for ( int i = 0 ; i < n; i++) { // Update the frequency of current character if (count.containsKey(s.charAt(i))) { count.put(s.charAt(i), count.get(s.charAt(i)) + 1 ); } else { count.put(s.charAt(i), 1 ); } // Check if the character is vowel or consonant if (isVowel(s.charAt(i))) { vo++; } else { co++; } } if (co == vo + 1 || co == vo) { // Store the denominator of the expression long deno = 1 ; // Calculate the denominator of the expression for (var item : count.entrySet()) { // Multiply denominator by factorial of // counts of all letters deno = (deno * fac.get(item.getValue())) % mod; } // Store the numerator long nume = fac.get(co) % mod; nume = (nume * fac.get(vo)) % mod; // Store the answer by dividing numerator by // denominator long ans = nume / deno; // Print the answer System.out.println(ans); } else { System.out.println( 0 ); } } public static void main(String[] args) { String S = "GADO" ; int l = S.length(); countAnagrams(S, l); } } // This code is contributed by phasing17. |
Python3
# Python 3 program for the above approach #include <bits/stdc++.h> mod = 1000000007 N = 1000001 fac = {} # Function to compute factorials till N def Precomputefact(): global fac ans = 1 # Iterate in the range [1, N] for i in range ( 1 ,N + 1 , 1 ): # Update ans to ans*i ans = (ans * i) % mod # Store the value of ans # in fac[i] fac[i] = ans return # Function to check whether the # current character is a vowel or not def isVowel(a): if (a = = 'A' or a = = 'E' or a = = 'I' or a = = 'O' or a = = 'U' ): return True else : return False # Function to count the number of # anagrams of S satisfying the # given condition def countAnagrams(s,n): # Store the factorials upto N global fac # Function Call to generate # all factorials upto n Precomputefact() # Create a hashmap to store # frequencies of all characters count = {} # Store the count of # vowels and consonants vo = 0 co = 0 # Iterate through all # characters in the string for i in range (n): # Update the frequency # of current character if s[i] in count: count[s[i]] + = 1 else : count[s[i]] = 1 # Check if the character # is vowel or consonant if (isVowel(s[i])): vo + = 1 else : co + = 1 # Check if ΣC==ΣV+1 or ΣC==ΣV if ((co = = vo + 1 ) or (co = = vo)): # Store the denominator deno = 1 # Calculate the denominator # of the expression for key,value in count.items(): # Multiply denominator by factorial # of counts of all letters deno = (deno * fac[value]) % mod # Store the numerator nume = fac[co] % mod nume = (nume * fac[vo]) % mod # Store the answer by dividing # numerator by denominator ans = nume / / deno # Print the answer print (ans) # Otherwise, print 0 else : print ( 0 ) # Driver Code if __name__ = = '__main__' : S = "GADO" l = len (S) countAnagrams(S, l) # This code is contributed by ipg2016107. |
C#
// C# program for the above approach using System; using System.Collections.Generic; using System.Linq; class GFG { static int mod = 1000000007; static int N = 1000001; static Dictionary< int , long > fac = new Dictionary< int , long >(); // Function to compute factorials till N static void Precomputefact() { long ans = 1; // Iterate in the range [1, N] for ( int i = 1; i <= N; i++) { // Update ans to ans*i ans = (ans * i) % mod; // Store the value of ans // in fac[i] fac[i] = ans; } } // Function to check whether the // current character is a vowel or not static bool IsVowel( char a) { return (a == 'A' || a == 'E' || a == 'I' || a == 'O' || a == 'U' ); } // Function to count the number of // anagrams of S satisfying the // given condition static void CountAnagrams( string s, int n) { // Store the factorials upto N // Function Call to generate // all factorials upto n Precomputefact(); // Create a hashmap to store // frequencies of all characters Dictionary< char , int > count = new Dictionary< char , int >(); // Store the count of // vowels and consonants int vo = 0; int co = 0; // Iterate through all // characters in the string for ( int i = 0; i < n; i++) { // Update the frequency // of current character if (count.ContainsKey(s[i])) { count[s[i]]++; } else { count[s[i]] = 1; } // Check if the character // is vowel or consonant if (IsVowel(s[i])) { vo++; } else { co++; } } // Check if ΣC==ΣV+1 or ΣC==ΣV if (co == vo + 1 || co == vo) { // Store the denominator long deno = 1; // Calculate the denominator // of the expression foreach ( var item in count) { // Multiply denominator by factorial // of counts of all letters deno = (deno * fac[item.Value]) % mod; } // Store the numerator long nume = fac[co] % mod; nume = (nume * fac[vo]) % mod; // Store the answer by dividing // numerator by denominator long ans = nume / deno; // Print the answer Console.WriteLine(ans); } else Console.WriteLine(0); } public static void Main( string [] args) { string S = "GADO" ; int l = S.Length; CountAnagrams(S, l); } } // This code is contributed by phasing17. |
Javascript
// JS program to implement the approach const mod = 1000000007; const N = 1000001; let fac = {}; // Function to compute factorials till N function Precomputefact() { let ans = 1; // Iterate in the range [1, N] for (let i = 1; i <= N; i++) { // Update ans to ans*i ans = (ans * i) % mod; // Store the value of ans in fac[i] fac[i] = ans; } return ; } // Function to check whether the current character is a vowel or not function isVowel(a) { if (a == "A" || a == "E" || a == "I" || a == "O" || a == "U" ) { return true ; } else { return false ; } } // Function to count the number of anagrams of S satisfying the given condition function countAnagrams(s, n) { // Store the factorials upto N // Function Call to generate all factorials upto n Precomputefact(); // Create a hashmap to store frequencies of all characters let count = {}; // Store the count of vowels and consonants let vo = 0; let co = 0; // Iterate through all characters in the string for (let i = 0; i < n; i++) { // Update the frequency of current character if (s[i] in count) { count[s[i]] += 1; } else { count[s[i]] = 1; } // Check if the character is vowel or consonant if (isVowel(s[i])) { vo += 1; } else { co += 1; } } // Check if ΣC==ΣV+1 or ΣC==ΣV if (co == vo + 1 || co == vo) { // Store the denominator of the expression let deno = 1; // Calculate the denominator of the expression for (let key of Object.keys(count)) { // Multiply denominator by factorial of counts of all letters deno = (deno * fac[count[key]]) % mod; } // Store the numerator let nume = fac[co] % mod; nume = (nume * fac[vo]) % mod; // Store the answer by dividing numerator by denominator let ans = Math.floor(nume / deno); // Print the answer console.log(ans); } else { // Otherwise, print 0 console.log(0); } } // Driver Code let S = "GADO" ; let l = S.length; countAnagrams(S, l); // This code is contributed by phasing17 |
4
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...