Open In App

Number of ways in which the substring in range [L, R] can be formed using characters out of the range

Last Updated : 18 Jun, 2022
Comments
Improve
Suggest changes
Like Article
Like
Report

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:
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:

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>

Output: 
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.
 


Next Article

Similar Reads