Given a string S and a range [L, R]. The task is to find the number of ways in which the sub-string in the range S[L, R] can be constructed using the characters that exist in the string but do not lie in the range S[L, R].
Examples:
Input: s = “cabcaab”, l = 1, r = 3
Output: 2
The substring is “abc”
s[4] + s[6] + s[0] = ‘a’ + ‘b’ + ‘c’ = “abc”
s[5] + s[6] + s[0] = ‘a’ + ‘b’ + ‘c’ = “abc”
Input: s = “aaaa”, l = 1, r = 2
Output: 2
Approach: The problem can be solved using hash-table and combinatorics. The following steps can be followed to solve the above problem:
- Count the frequency of every character that does not lie in the range L and R in the hash-table(say freq).
- Iterate from L to R separately and calculate the number of ways.
- For every character in range L and R, the number of ways is multiplied by freq[s[i]-‘a’] and decreases the value of freq[s[i]-‘a’] by 1.
- In case the freq[s[i]-‘a’] value is 0, we do not have any characters to fill up that place, hence the number of ways will be 0.
- In the end, the overall multiplication will be our answer.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Function to return the number of // ways to form the sub-string int calculateWays(string s, int n, int l, int r) { // Initialize a hash-table // with 0 int freq[26]; memset (freq, 0, sizeof freq); // Iterate in the string and count // the frequency of characters that // do not lie in the range L and R for ( int i = 0; i < n; i++) { // Out of range characters if (i < l || i > r) freq[s[i] - 'a' ]++; } // Stores the final number of ways int ways = 1; // Iterate for the sub-string in the range // L and R for ( int i = l; i <= r; i++) { // If exists then multiply // the number of ways and // decrement the frequency if (freq[s[i] - 'a' ]) { ways = ways * freq[s[i] - 'a' ]; freq[s[i] - 'a' ]--; } // If does not exist // the sub-string cannot be formed else { ways = 0; break ; } } // Return the answer return ways; } // Driver code int main() { string s = "cabcaab" ; int n = s.length(); int l = 1, r = 3; cout << calculateWays(s, n, l, r); return 0; } |
Java
// Java implementation of the approach class GfG { // Function to return the number of // ways to form the sub-string static int calculateWays(String s, int n, int l, int r) { // Initialize a hash-table // with 0 int freq[] = new int [ 26 ]; // Iterate in the string and count // the frequency of characters that // do not lie in the range L and R for ( int i = 0 ; i < n; i++) { // Out of range characters if (i < l || i > r) freq[s.charAt(i)- 'a' ]++; } // Stores the final number of ways int ways = 1 ; // Iterate for the sub-string in the range // L and R for ( int i = l; i <= r; i++) { // If exists then multiply // the number of ways and // decrement the frequency if (freq[s.charAt(i) - 'a' ] != 0 ) { ways = ways * freq[s.charAt(i) - 'a' ]; freq[s.charAt(i) - 'a' ]--; } // If does not exist // the sub-string cannot be formed else { ways = 0 ; break ; } } // Return the answer return ways; } // Driver code public static void main(String[] args) { String s = "cabcaab" ; int n = s.length(); int l = 1 , r = 3 ; System.out.println(calculateWays(s, n, l, r)); } } |
Python3
# Python 3 implementation of the approach # Function to return the number of # ways to form the sub-string def calculateWays(s, n, l, r): # Initialize a hash-table # with 0 freq = [ 0 for i in range ( 26 )] # Iterate in the string and count # the frequency of characters that # do not lie in the range L and R for i in range (n): # Out of range characters if (i < l or i > r): freq[ ord (s[i]) - ord ( 'a' )] + = 1 # Stores the final number of ways ways = 1 # Iterate for the sub-string in the range # L and R for i in range (l, r + 1 , 1 ): # If exists then multiply # the number of ways and # decrement the frequency if (freq[ ord (s[i]) - ord ( 'a' )]): ways = ways * freq[ ord (s[i]) - ord ( 'a' )] freq[ ord (s[i]) - ord ( 'a' )] - = 1 # If does not exist # the sub-string cannot be formed else : ways = 0 break # Return the answer return ways # Driver code if __name__ = = '__main__' : s = "cabcaab" n = len (s) l = 1 r = 3 print (calculateWays(s, n, l, r)) # This code is contributed by # Surendra_Gangwar |
C#
// C# implementation of the approach using System; class GfG { // Function to return the number of // ways to form the sub-string static int calculateWays(String s, int n, int l, int r) { // Initialize a hash-table // with 0 int []freq = new int [26]; // Iterate in the string and count // the frequency of characters that // do not lie in the range L and R for ( int i = 0; i < n; i++) { // Out of range characters if (i < l || i > r) freq[s[i]- 'a' ]++; } // Stores the final number of ways int ways = 1; // Iterate for the sub-string in the range // L and R for ( int i = l; i <= r; i++) { // If exists then multiply // the number of ways and // decrement the frequency if (freq[s[i] - 'a' ] != 0) { ways = ways * freq[s[i] - 'a' ]; freq[s[i] - 'a' ]--; } // If does not exist // the sub-string cannot be formed else { ways = 0; break ; } } // Return the answer return ways; } // Driver code public static void Main() { String s = "cabcaab" ; int n = s.Length; int l = 1, r = 3; Console.WriteLine(calculateWays(s, n, l, r)); } } /* This code contributed by PrinciRaj1992 */ |
PHP
<?php // PHP implementation of the approach // Function to return the number of // ways to form the sub-string function calculateWays( $s , $n , $l , $r ) { // Initialize a hash-table // with 0 $freq = array (); for ( $i = 0; $i < 26 ; $i ++ ) { $freq [ $i ] = 0; } // Iterate in the string and count // the frequency of characters that // do not lie in the range L and R for ( $i = 0; $i < $n ; $i ++ ) { // Out of range characters if ( $i < $l || $i > $r ) $freq [ord( $s [ $i ]) - 97]++; } // Stores the final number of ways $ways = 1; // Iterate for the sub-string in the range // L and R for ( $i = $l ; $i <= $r ; $i ++) { // If exists then multiply // the number of ways and // decrement the frequency if ( $freq [ord( $s [ $i ]) - 97]) { $ways = $ways * $freq [ord( $s [ $i ]) - 97]; $freq [ord( $s [ $i ]) - 97]--; } // If does not exist // the sub-string cannot be formed else { $ways = 0; break ; } } // Return the answer return $ways ; } // Driver code $s = "cabcaab" ; $n = strlen ( $s ); $l = 1; $r = 3; echo calculateWays( $s , $n , $l , $r ); // This code is contributed by ihritik ?> |
Javascript
<script> // javascript implementation of the approach // Function to return the number of // ways to form the sub-string function calculateWays( s , n , l , r) { // Initialize a hash-table // with 0 var freq = Array(26).fill(0); // Iterate in the string and count // the frequency of characters that // do not lie in the range L and R for (i = 0; i < n; i++) { // Out of range characters if (i < l || i > r) freq[s.charCodeAt(i) - 'a' .charCodeAt(0)]++; } // Stores the final number of ways var ways = 1; // Iterate for the sub-string in the range // L and R for (i = l; i <= r; i++) { // If exists then multiply // the number of ways and // decrement the frequency if (freq[s.charCodeAt(i) - 'a' .charCodeAt(0)] != 0) { ways = ways * freq[s.charCodeAt(i) - 'a' .charCodeAt(0)]; freq[s.charCodeAt(i) - 'a' .charCodeAt(0)]--; } // If does not exist // the sub-string cannot be formed else { ways = 0; break ; } } // Return the answer return ways; } // Driver code var s = "cabcaab" ; var n = s.length; var l = 1, r = 3; document.write(calculateWays(s, n, l, r)); // This code contributed by umadevi9616 </script> |
2
Time Complexity: O(N), where N is the length of the string. As, we are using a loop to traverse N times to get the frequencies of the characters present in the string.
Auxiliary Space: O(26), as we are using extra space for the freq map.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!