Skip to content
Related Articles

Related Articles

Improve Article

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

  • Difficulty Level : Hard
  • Last Updated : 18 May, 2021

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 decrease the value of freq[s[i]-‘a’] by 1.
  • In case the freq[s[i]-‘a’] value is 0, we donot have any characters to fill up that place, hence the number of ways will be 0.
  • At 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 mulitply
        // 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 mulitply
        // 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 mulitply
        # 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 mulitply
        // 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 mulitply
        // 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 mulitply
            // 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. 
Auxiliary Space: O(1)
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :