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++ 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 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));
} } |
# 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# 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 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 ?> |
<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.