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:
- “gE”
- “gEEk”
- “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++ 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)
{ //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 ( isupper (S[j]))upper++;
else lower++;
//if lower and upper are equal
if (upper==lower)ans++;
}
}
return ans;
} // Driver Code int main()
{ string S = "gEEk" ;
cout << countSubstring(S, S.length());
return 0;
} //code contributed by shubhamrajput6156 |
// 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 |
# 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. |
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));
}
} |
// 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)); |
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++ 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 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 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# 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 |
<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> |
3
Time Complexity: O(N)
Auxiliary Space: O(N) because map prevSum will be taking extra space