Related Articles

# Number of substrings having an equal number of lowercase and uppercase letters

• Difficulty Level : Hard
• 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 ``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 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

 ``
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 experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up