Skip to content
Related Articles

Related Articles

Improve Article
Number of substrings having an equal number of lowercase and uppercase letters
  • Difficulty Level : Expert
  • Last Updated : 25 May, 2021

Given string S consists of lowercase and uppercase letters, the task is to find the number of substrings having an equal number of lowercase and uppercase letters.

Examples:

Input: S = “gEEk”
Output: 3
Explanation:
The following are the substrings having an equal number of lowercase and uppercase letters:

  1. “gE”
  2. “gEEk”
  3. “Ek”

Therefore, the total count of substrings is 3.

Input: S = “WomensDAY”
Output: 4



Naive Approach: The simplest approach to solve the given problem is to generate all possible substring of the given string S and increment the count of a substring by 1 if that substring contains an equal number of lowercase and uppercase letters. After checking for all the substrings, print the value of the count as the result. 

Time Complexity: O(N3)
Auxiliary Space: O(1)

Efficient Approach: The given problem can be solved by considering each lowercase and uppercase letter as 1 and -1 respectively, and then find the count of subarray having sum 0. Follow the steps to solve the problem:

  • Initialize a HashMap, say M that stores the frequency of the sum of all the prefixes.
  • Initialize a variable, say, currentSum as 0 and res as 0 that stores the sum of each prefix and count of the resultant substrings respectively.
  • Traverse the string and perform the following steps:
    • If the current character is uppercase, then increment the value of currentSum by 1. Otherwise, decrease the value of currentSum by -1.
    • If the value of currentSum is 0, then increment the value of res by 1.
    • If the value of currentSum exists in the map M, then increment the value of res by M[currentSum].
    • Increment the frequency of currentSum in the HashMap M by 1.
  • After completing the above steps, print the value of res as the result.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the count of
// substrings having an equal number
// of uppercase and lowercase characters
int countSubstring(string& S, int N)
{
    // Stores the count of prefixes
    // having sum S considering uppercase
    // and lowercase characters as 1 and -1
    unordered_map<int, int> prevSum;
 
    // Stores the count of substrings
    // having equal number of lowercase
    // and uppercase characters
    int res = 0;
 
    // Stores the sum obtained so far
    int currentSum = 0;
 
    for (int i = 0; i < N; i++) {
 
        // If the character is uppercase
        if (S[i] >= 'A' and S[i] <= 'Z') {
            currentSum++;
        }
 
        // Otherwise
        else
            currentSum--;
 
        // If currsum is o
        if (currentSum == 0)
            res++;
 
        // If the current sum exists in
        // the HashMap prevSum
        if (prevSum.find(currentSum)
            != prevSum.end()) {
 
            // Increment the resultant
            // count by 1
            res += (prevSum[currentSum]);
        }
 
        // Update the frequency of the
        // current sum by 1
        prevSum[currentSum]++;
    }
 
    // Return the resultant count of
    // the subarrays
    return res;
}
 
// Driver Code
int main()
{
    string S = "gEEk";
    cout << countSubstring(S, S.length());
 
    return 0;
}


Java




// Java program for the above approach
import java.util.HashMap;
 
class GFG{
 
// Function to find the count of
// substrings having an equal number
// of uppercase and lowercase characters
static int countSubstring(String S, int N)
{
     
    // Stores the count of prefixes
    // having sum S considering uppercase
    // and lowercase characters as 1 and -1
    HashMap<Integer, Integer> prevSum = new HashMap<>();
 
    // Stores the count of substrings
    // having equal number of lowercase
    // and uppercase characters
    int res = 0;
 
    // Stores the sum obtained so far
    int currentSum = 0;
 
    for(int i = 0; i < N; i++)
    {
         
        // If the character is uppercase
        if (S.charAt(i) >= 'A' && S.charAt(i) <= 'Z')
        {
            currentSum++;
        }
 
        // Otherwise
        else
            currentSum--;
 
        // If currsum is 0
        if (currentSum == 0)
            res++;
 
        // If the current sum exists in
        // the HashMap prevSum
        if (prevSum.containsKey(currentSum))
        {
             
            // Increment the resultant
            // count by 1
            res += prevSum.get(currentSum);
        }
 
        // Update the frequency of the
        // current sum by 1
        prevSum.put(currentSum,
                    prevSum.getOrDefault(currentSum, 0) + 1);
    }
 
    // Return the resultant count of
    // the subarrays
    return res;
}
 
// Driver Code
public static void main(String[] args)
{
    String S = "gEEk";
    System.out.println(countSubstring(S, S.length()));
}
}
 
// This code is contributed by abhinavjain194


Python3




# Python3 program for the above approach
 
# Function to find the count of
# substrings having an equal number
# of uppercase and lowercase characters
def countSubstring(S, N):
     
    # Stores the count of prefixes
    # having sum S considering uppercase
    # and lowercase characters as 1 and -1
    prevSum = {}
 
    # Stores the count of substrings
    # having equal number of lowercase
    # and uppercase characters
    res = 0
 
    # Stores the sum obtained so far
    currentSum = 0
 
    for i in range(N):
         
        # If the character is uppercase
        if (S[i] >= 'A' and S[i] <= 'Z'):
            currentSum += 1
 
        # Otherwise
        else:
            currentSum -= 1
 
        # If currsum is o
        if (currentSum == 0):
            res += 1
 
        # If the current sum exists in
        # the HashMap prevSum
        if (currentSum in prevSum):
             
            # Increment the resultant
            # count by 1
            res += (prevSum[currentSum])
 
        # Update the frequency of the
        # current sum by 1
        if currentSum in prevSum:
            prevSum[currentSum] += 1
        else:
            prevSum[currentSum] = 1
 
    # Return the resultant count of
    # the subarrays
    return res
 
# Driver Code
if __name__ == '__main__':
     
    S = "gEEk"
    print(countSubstring(S, len(S)))
 
# This code is contributed by bgangwar59


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find the count of
// substrings having an equal number
// of uppercase and lowercase characters
static int countSubstring(String S, int N)
{
     
    // Stores the count of prefixes
    // having sum S considering uppercase
    // and lowercase characters as 1 and -1
    Dictionary<int,
               int> prevSum = new Dictionary<int,
                                             int>();
 
    // Stores the count of substrings
    // having equal number of lowercase
    // and uppercase characters
    int res = 0;
 
    // Stores the sum obtained so far
    int currentSum = 0;
 
    for(int i = 0; i < N; i++)
    {
         
        // If the character is uppercase
        if (S[i] >= 'A' && S[i] <= 'Z')
        {
            currentSum++;
        }
 
        // Otherwise
        else
            currentSum--;
 
        // If currsum is 0
        if (currentSum == 0)
            res++;
 
        // If the current sum exists in
        // the Dictionary prevSum
        if (prevSum.ContainsKey(currentSum))
        {
             
            // Increment the resultant
            // count by 1
            res += prevSum[currentSum];
            prevSum[currentSum] = prevSum[currentSum] + 1;
        }
        else
            prevSum.Add(currentSum, 1);
    }
 
    // Return the resultant count of
    // the subarrays
    return res;
}
 
// Driver Code
public static void Main(String[] args)
{
    String S = "gEEk";
    Console.WriteLine(countSubstring(S, S.Length));
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
 
// Javascript program for the above approach
 
// Function to find the count of
// substrings having an equal number
// of uppercase and lowercase characters
function countSubstring(S, N)
{
    // Stores the count of prefixes
    // having sum S considering uppercase
    // and lowercase characters as 1 and -1
    var prevSum = new Map();
 
    // Stores the count of substrings
    // having equal number of lowercase
    // and uppercase characters
    var res = 0;
 
    // Stores the sum obtained so far
    var currentSum = 0;
 
    for (var i = 0; i < N; i++) {
 
        // If the character is uppercase
        if (S[i] >= 'A' && S[i] <= 'Z') {
            currentSum++;
        }
 
        // Otherwise
        else
            currentSum--;
 
        // If currsum is o
        if (currentSum == 0)
            res++;
 
        // If the current sum exists in
        // the HashMap prevSum
        if (prevSum.has(currentSum)) {
 
            // Increment the resultant
            // count by 1
            res += (prevSum.get(currentSum));
        }
 
        // Update the frequency of the
        // current sum by 1
        if(prevSum.has(currentSum))
            prevSum.set(currentSum, prevSum.get(currentSum)+1)
        else
            prevSum.set(currentSum, 1)
    }
 
    // Return the resultant count of
    // the subarrays
    return res;
}
 
// Driver Code
var S = "gEEk";
document.write( countSubstring(S, S.length));
 
</script>


Output: 

3

 

Time Complexity: O(N)
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 industry experts, please refer DSA Live Classes




My Personal Notes arrow_drop_up
Recommended Articles
Page :