Open In App

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

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.

Steps that were to follow the above approach:

• We will traverse the array using two for loops
• We will take ans variable to 0, to store answer.
• In each iteration we will set lower and upper as 0.
• If a upper case come then we will increase the upper else we will increase the lower
• If upper and lower become equal then we will increase the count of our answer by 1
• In last we will return the ans variable.

Below is the code to implement the above steps:

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)``{``      ``//Variable to store answer and count``      ``//lower and upper case alphabets``    ``int` `ans=0,lower=0,upper=0;``  ` `      ``//iterating``    ``for``(``int` `i=0;i

Java

 `// Java program for the above approach``import` `java.util.*;` `class` `Main {``// Function to find the count of``// substrings having an equal number``// of uppercase and lowercase characters``public` `static` `int` `countSubstring(String S, ``int` `N) {``// Variable to store answer and count``// lower and upper case alphabets``int` `ans = ``0``, lower = ``0``, upper = ``0``;``    ``// iterating``    ``for` `(``int` `i = ``0``; i < S.length(); i++) {``        ``// setting lower and upper to 0``        ``upper = ``0``;``        ``lower = ``0``;` `        ``for` `(``int` `j = i; j < S.length(); j++) {``            ``// if upper case le==alphabet``            ``if` `(Character.isUpperCase(S.charAt(j)))``                ``upper++;``            ``else``                ``lower++;``            ``// if lower and upper are equal``            ``if` `(upper == lower)``                ``ans++;``        ``}``    ``}``    ``return` `ans;``}` `// Driver Code``public` `static` `void` `main(String args[]) {``    ``String S = ``"gEEk"``;``    ``System.out.println(countSubstring(S, S.length()));``}``}` `//Code contributed by Vaibhav`

Python3

 `# Convert to python code` `# Function to find the count of substrings having an equal``# number of uppercase and lowercase characters``def` `countSubstring(S):``    ``# Variable to store answer and count lower and upper case alphabets``    ``ans, lower, upper ``=` `0``, ``0``, ``0` `    ``# iterating``    ``for` `i ``in` `range``(``len``(S)):``        ``# setting lower and upper to 0``        ``upper ``=` `0``        ``lower ``=` `0` `        ``for` `j ``in` `range``(i, ``len``(S)):``            ``# if upper case alphabet``            ``if` `S[j].isupper():``                ``upper ``+``=` `1``            ``else``:``                ``lower ``+``=` `1``            ``# if lower and upper are equal``            ``if` `upper ``=``=` `lower:``                ``ans ``+``=` `1` `    ``return` `ans` `# Driver Code``S ``=` `"gEEk"``print``(countSubstring(S))` `# The code is contributed by Nidhi goel.`

C#

 `using` `System;` `public` `class` `GFG``{``    ``// Function to find the count of substrings having an equal``    ``// number of uppercase and lowercase characters``    ``public` `static` `int` `CountSubstring(``string` `S)``    ``{``        ``// Variable to store the answer and count lower and upper``       ``// case alphabets``        ``int` `ans = 0, lower = 0, upper = 0;` `        ``// Iterating through the string``        ``for` `(``int` `i = 0; i < S.Length; i++)``        ``{``            ``// Resetting lower and upper to 0 for each iteration``            ``upper = 0;``            ``lower = 0;` `            ``for` `(``int` `j = i; j < S.Length; j++)``            ``{``                ``// If it's an upper case alphabet``                ``if` `(Char.IsUpper(S[j]))``                ``{``                    ``upper++;``                ``}``                ``else``                ``{``                    ``lower++;``                ``}` `                ``// If the count of lower and upper case characters``               ``// are equal``                ``if` `(upper == lower)``                ``{``                    ``ans++;``                ``}``            ``}``        ``}` `        ``return` `ans;``    ``}` `    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``string` `S = ``"gEEk"``;``        ``Console.WriteLine(CountSubstring(S));``    ``}``}`

Javascript

 `// Function to find the count of substrings having an equal number of uppercase and lowercase characters``function` `countSubstring(S, N) {``    ``// Variable to store answer and count lower and upper case alphabets``    ``let ans = 0,``        ``lower = 0,``        ``upper = 0;` `    ``// iterating``    ``for` `(let i = 0; i < S.length; i++) {``        ``// setting lower and upper to 0``        ``upper = 0;``        ``lower = 0;` `        ``for` `(let j = i; j < S.length; j++) {``            ``// if upper case alphabet``            ``if` `(S[j] === S[j].toUpperCase()) upper++;``            ``else` `lower++;``            ``// if lower and upper are equal``            ``if` `(upper == lower) ans++;``        ``}``    ``}``    ``return` `ans;``}` `// Driver Code``let S = ``"gEEk"``;``console.log(countSubstring(S, S.length));`

Output

```3

```

Time Complexity: O(N^2)
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(N) because map prevSum will be taking extra space