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++
#include <bits/stdc++.h>
using namespace std;
int countSubstring(string& S, int N)
{
int ans=0,lower=0,upper=0;
for ( int i=0;i<S.length();i++){
upper=0;
lower=0;
for ( int j=i;j<S.length();j++){
if ( isupper (S[j]))upper++;
else lower++;
if (upper==lower)ans++;
}
}
return ans;
}
int main()
{
string S = "gEEk" ;
cout << countSubstring(S, S.length());
return 0;
}
|
Java
import java.util.*;
class Main {
public static int countSubstring(String S, int N) {
int ans = 0 , lower = 0 , upper = 0 ;
for ( int i = 0 ; i < S.length(); i++) {
upper = 0 ;
lower = 0 ;
for ( int j = i; j < S.length(); j++) {
if (Character.isUpperCase(S.charAt(j)))
upper++;
else
lower++;
if (upper == lower)
ans++;
}
}
return ans;
}
public static void main(String args[]) {
String S = "gEEk" ;
System.out.println(countSubstring(S, S.length()));
}
}
|
Python3
def countSubstring(S):
ans, lower, upper = 0 , 0 , 0
for i in range ( len (S)):
upper = 0
lower = 0
for j in range (i, len (S)):
if S[j].isupper():
upper + = 1
else :
lower + = 1
if upper = = lower:
ans + = 1
return ans
S = "gEEk"
print (countSubstring(S))
|
C#
using System;
public class GFG
{
public static int CountSubstring( string S)
{
int ans = 0, lower = 0, upper = 0;
for ( int i = 0; i < S.Length; i++)
{
upper = 0;
lower = 0;
for ( int j = i; j < S.Length; j++)
{
if (Char.IsUpper(S[j]))
{
upper++;
}
else
{
lower++;
}
if (upper == lower)
{
ans++;
}
}
}
return ans;
}
public static void Main( string [] args)
{
string S = "gEEk" ;
Console.WriteLine(CountSubstring(S));
}
}
|
Javascript
function countSubstring(S, N) {
let ans = 0,
lower = 0,
upper = 0;
for (let i = 0; i < S.length; i++) {
upper = 0;
lower = 0;
for (let j = i; j < S.length; j++) {
if (S[j] === S[j].toUpperCase()) upper++;
else lower++;
if (upper == lower) ans++;
}
}
return ans;
}
let S = "gEEk" ;
console.log(countSubstring(S, S.length));
|
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++
#include <bits/stdc++.h>
using namespace std;
int countSubstring(string& S, int N)
{
unordered_map< int , int > prevSum;
int res = 0;
int currentSum = 0;
for ( int i = 0; i < N; i++) {
if (S[i] >= 'A' and S[i] <= 'Z' ) {
currentSum++;
}
else
currentSum--;
if (currentSum == 0)
res++;
if (prevSum.find(currentSum)
!= prevSum.end()) {
res += (prevSum[currentSum]);
}
prevSum[currentSum]++;
}
return res;
}
int main()
{
string S = "gEEk" ;
cout << countSubstring(S, S.length());
return 0;
}
|
Java
import java.util.HashMap;
class GFG{
static int countSubstring(String S, int N)
{
HashMap<Integer, Integer> prevSum = new HashMap<>();
int res = 0 ;
int currentSum = 0 ;
for ( int i = 0 ; i < N; i++)
{
if (S.charAt(i) >= 'A' && S.charAt(i) <= 'Z' )
{
currentSum++;
}
else
currentSum--;
if (currentSum == 0 )
res++;
if (prevSum.containsKey(currentSum))
{
res += prevSum.get(currentSum);
}
prevSum.put(currentSum,
prevSum.getOrDefault(currentSum, 0 ) + 1 );
}
return res;
}
public static void main(String[] args)
{
String S = "gEEk" ;
System.out.println(countSubstring(S, S.length()));
}
}
|
Python3
def countSubstring(S, N):
prevSum = {}
res = 0
currentSum = 0
for i in range (N):
if (S[i] > = 'A' and S[i] < = 'Z' ):
currentSum + = 1
else :
currentSum - = 1
if (currentSum = = 0 ):
res + = 1
if (currentSum in prevSum):
res + = (prevSum[currentSum])
if currentSum in prevSum:
prevSum[currentSum] + = 1
else :
prevSum[currentSum] = 1
return res
if __name__ = = '__main__' :
S = "gEEk"
print (countSubstring(S, len (S)))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int countSubstring(String S, int N)
{
Dictionary< int ,
int > prevSum = new Dictionary< int ,
int >();
int res = 0;
int currentSum = 0;
for ( int i = 0; i < N; i++)
{
if (S[i] >= 'A' && S[i] <= 'Z' )
{
currentSum++;
}
else
currentSum--;
if (currentSum == 0)
res++;
if (prevSum.ContainsKey(currentSum))
{
res += prevSum[currentSum];
prevSum[currentSum] = prevSum[currentSum] + 1;
}
else
prevSum.Add(currentSum, 1);
}
return res;
}
public static void Main(String[] args)
{
String S = "gEEk" ;
Console.WriteLine(countSubstring(S, S.Length));
}
}
|
Javascript
<script>
function countSubstring(S, N)
{
var prevSum = new Map();
var res = 0;
var currentSum = 0;
for ( var i = 0; i < N; i++) {
if (S[i] >= 'A' && S[i] <= 'Z' ) {
currentSum++;
}
else
currentSum--;
if (currentSum == 0)
res++;
if (prevSum.has(currentSum)) {
res += (prevSum.get(currentSum));
}
if (prevSum.has(currentSum))
prevSum.set(currentSum, prevSum.get(currentSum)+1)
else
prevSum.set(currentSum, 1)
}
return res;
}
var S = "gEEk" ;
document.write( countSubstring(S, S.length));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N) because map prevSum will be taking extra space