# 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)

My Personal Notes arrow_drop_up
Recommended Articles
Page :