Given a binary string s, the task is to calculate the number of such substrings where the count of 1's is strictly greater than the count of 0's.
Examples
Input: s = "110011"
Output: 11
Explanation: Substrings in which the count of 1's is strictly greater than the count of 0's are {1}, {11}, {110}, {11001}, {110011}, {1}, {10011}, {011}, {1}, {11}, {1}.Input: s = "011"
Output: 4
Explanation: There are 4 substring which has more 1s than 0s. i.e {011}, {1}, {11} and {1}.Input: s = "0000"
Output: 0
Explanation: There is no substring with more 1s than 0s.
Table of Content
[Naive Approach] Generate all Substrings - O(n ^ 2) Time and O(1) Space
The simplest approach to solve the problem is to generate all substrings and count the number of 1s and 0s in each substring. Increase the count of those substrings that contain the count of 1s greater than the count of 0s. Finally, print the count obtained.
- Start from every index i of the string and generate all possible substrings starting from i.
- For each substring, maintain two counters: ones --> count of '1' and zeros --> count of '0'
- Traverse the substring character by character and update the counts accordingly.
- After adding each character, check whether ones > zeros. If yes, increment result by 1.
#include <bits/stdc++.h>
using namespace std;
// Function to count substrings
// having more 1's than 0's
int countSubstring(string s)
{
int n = s.size();
// Stores final count
int cnt = 0;
// Generate all substrings
for (int i = 0; i < n; i++)
{
int ones = 0;
int zeros = 0;
for (int j = i; j < n; j++)
{
// Count zeros and ones
if (s[j] == '0')
{
zeros++;
}
else
{
ones++;
}
// If ones are greater than zeros
if (ones > zeros)
{
cnt++;
}
}
}
return cnt;
}
int main()
{
string s = "110011";
int ans = countSubstring(s);
cout << ans << endl;
return 0;
}
import java.util.*;
public class GFG {
// Function to count substrings
// having more 1's than 0's
static int countSubstring(String s)
{
int n = s.length();
// Stores final count
int cnt = 0;
// Generate all substrings
for (int i = 0; i < n; i++) {
int ones = 0;
int zeros = 0;
for (int j = i; j < n; j++) {
// Count zeros and ones
if (s.charAt(j) == '0') {
zeros++;
}
else {
ones++;
}
// If ones are greater than zeros
if (ones > zeros) {
cnt++;
}
}
}
// Return final answer
return cnt;
}
public static void main(String[] args)
{
String s = "110011";
int ans = countSubstring(s);
System.out.println(ans);
}
}
# Function to count substrings
# having more 1's than 0's
def countSubstring(s):
n = len(s)
# Stores final count
cnt = 0
# Generate all substrings
for i in range(n):
ones = 0
zeros = 0
for j in range(i, n):
# Count zeros and ones
if s[j] == '0':
zeros += 1
else:
ones += 1
# If ones are greater than zeros
if ones > zeros:
cnt += 1
# Return final answer
return cnt
# Driver Code
if __name__ == "__main__":
s = "110011"
ans = countSubstring(s)
print(ans)
using System;
class GFG {
// Function to count substrings
// having more 1's than 0's
static int countSubstring(string s)
{
int n = s.Length;
// Stores final count
int cnt = 0;
// Generate all substrings
for (int i = 0; i < n; i++) {
int ones = 0;
int zeros = 0;
for (int j = i; j < n; j++) {
// Count zeros and ones
if (s[j] == '0') {
zeros++;
}
else {
ones++;
}
// If ones are greater than zeros
if (ones > zeros) {
cnt++;
}
}
}
// Return final answer
return cnt;
}
static void Main()
{
string s = "110011";
int ans = countSubstring(s);
Console.WriteLine(ans);
}
}
// Function to count substrings
// having more 1's than 0's
function countSubstring(s)
{
let n = s.length;
// Stores final count
let cnt = 0;
// Generate all substrings
for (let i = 0; i < n; i++) {
let ones = 0;
let zeros = 0;
for (let j = i; j < n; j++) {
// Count zeros and ones
if (s[j] === "0") {
zeros++;
}
else {
ones++;
}
// If ones are greater than zeros
if (ones > zeros) {
cnt++;
}
}
}
// Return final answer
return cnt;
}
// Driver Code
let s = "110011";
let ans = countSubstring(s);
console.log(ans);
Output
11
[Expected Approach] Using Prefix Sum - O(n) Time and O(n) Space
The idea is to treat '1' as +1 and '0' as -1, so a substring with a positive sum has more 1s than 0s. We use prefix balances to avoid checking every substring separately. A frequency array stores how many times each balance occurs, while minus tracks invalid states where zeros are greater than or equal to ones. By updating these values dynamically, we count all valid substrings in linear time.
- Treat every '1' as +1 and every '0' as -1.
- Use a prefix sum concept where a positive difference means the substring has more 1s than 0s.
- Store frequencies of prefix balances in the mp[] array.
- Variable minus keeps track of invalid prefix states where zeros are greater than or equal to ones.
- For every starting index, count valid substrings using:
valid = total suffixes - invalid suffixes. - Update frequency counts and minus dynamically while moving the starting index forward.
Consider the following dry run for better understanding: s = "011"
- Initial values: n = 3, zero = 3, cur = 3, minus = 0, ans = 0
- Step 1: Build Prefix Frequencies
For i = 0 --> s[0] = '0' --> cur = 2, cur <= zero so minus = 1, mp[2] = 1
For i = 1 --> s[1] = '1' --> cur = 3, cur <= zero so minus = 2, mp[3] = 1
For i = 2 --> s[2] = '1' --> cur = 4, minus = 2, mp[4] = 1
Final State: mp[2] = 1, mp[3] = 1, mp[4] = 1, zero = 3, minus = 2, ans = 0 - Step 2: Count Valid Substrings
For i = 0 --> s[0] = '0' --> ans += (3 - 0 - 2) = 1 --> ans = 1, mp[2]-- = 0, zero = 2,
minus-- = 1, minus -= mp[3](1) = 0
For i = 1 --> s[1] = '1' --> ans += (3 - 1 - 0) = 2 --> ans = 3, mp[3]-- = 0, zero = 3, minus += mp[3](0) = 0
For i = 2 --> s[2] = '1' --> ans += (3 - 2 - 0) = 1 --> ans = 4, mp[4]-- = 0, zero = 4, minus += mp[4](0) = 0
Final answer : ans = 4. Valid Substrings : {011}, {1}, {11} and {1}.
#include <bits/stdc++.h>
using namespace std;
int countSubstring(string s)
{
// Length of the string
int n = s.size();
// Final answer
int ans = 0;
// "zero" acts as the base index in frequency array
// We shift indices by n to avoid negative indexing
int zero = n;
// Stores count of invalid prefix states
// (where number of 0's >= number of 1's)
int minus = 0;
// Frequency array to store occurrences
// of prefix balances
vector<int> mp(2 * n + 1, 0);
// Current prefix balance
int cur = zero;
// Step 1: Build prefix balance frequencies
for (auto i : s)
{
// Treat:
// '1' as +1
// '0' as -1
if (i == '0')
cur--;
else
cur++;
// If current balance <= base balance,
// then substring is invalid
if (cur <= zero)
{
minus++;
}
// Store frequency of current balance
mp[cur]++;
}
// Step 2: Count valid substrings
for (int i = 0; i < n; i++)
{
// Total substrings starting from index i
// = (n - i)
// Subtract invalid substrings
ans += (n - i - minus);
// Update values while moving start index
// Case 1: Current character is '1'
if (s[i] == '1')
{
// Remove old prefix balance frequency
mp[zero + 1]--;
// Shift base balance
zero++;
// Update invalid count
minus += mp[zero];
}
// Case 2: Current character is '0'
else
{
// Remove old prefix balance frequency
mp[zero - 1]--;
// Shift base balance
zero--;
// Current invalid state removed
minus--;
// Remove additional invalid balances
minus -= mp[zero + 1];
}
}
// Return final answer
return ans;
}
int main()
{
string s = "110011";
cout << countSubstring(s);
return 0;
}
import java.util.*;
public class GFG {
static int countSubstring(String s)
{
// Length of string
int n = s.length();
// Final answer
int ans = 0;
// Base index to avoid negative indexing
int zero = n;
// Stores count of invalid prefix states
int minus = 0;
// Frequency array for prefix balances
int[] mp = new int[2 * n + 1];
// Current prefix balance
int cur = zero;
// Step 1: Build prefix balance frequencies
for (char ch : s.toCharArray()) {
// Treat:
// '1' as +1
// '0' as -1
if (ch == '0')
cur--;
else
cur++;
// Invalid prefix state
if (cur <= zero) {
minus++;
}
// Store frequency
mp[cur]++;
}
// Step 2: Count valid substrings
for (int i = 0; i < n; i++) {
// Total substrings - invalid substrings
ans += (n - i - minus);
// If current character is '1'
if (s.charAt(i) == '1') {
mp[zero + 1]--;
zero++;
minus += mp[zero];
}
// If current character is '0'
else {
mp[zero - 1]--;
zero--;
minus--;
minus -= mp[zero + 1];
}
}
return ans;
}
public static void main(String[] args)
{
String s = "110011";
System.out.println(countSubstring(s));
}
}
def countSubstring(s):
# Length of string
n = len(s)
# Final answer
ans = 0
# Base index to avoid negative indexing
zero = n
# Stores count of invalid prefix states
minus = 0
# Frequency array for prefix balances
mp = [0] * (2 * n + 1)
# Current prefix balance
cur = zero
# Step 1: Build prefix balance frequencies
for ch in s:
# Treat:
# '1' as +1
# '0' as -1
if ch == '0':
cur -= 1
else:
cur += 1
# Invalid prefix state
if cur <= zero:
minus += 1
# Store frequency
mp[cur] += 1
# Step 2: Count valid substrings
for i in range(n):
# Total substrings - invalid substrings
ans += (n - i - minus)
# If current character is '1'
if s[i] == '1':
mp[zero + 1] -= 1
zero += 1
minus += mp[zero]
# If current character is '0'
else:
mp[zero - 1] -= 1
zero -= 1
minus -= 1
minus -= mp[zero + 1]
return ans
# Driver Code
if __name__ == "__main__":
s = "110011"
print(countSubstring(s))
using System;
class GFG {
static int countSubstring(string s)
{
// Length of string
int n = s.Length;
// Final answer
int ans = 0;
// Base index to avoid negative indexing
int zero = n;
// Stores count of invalid prefix states
int minus = 0;
// Frequency array for prefix balances
int[] mp = new int[2 * n + 1];
// Current prefix balance
int cur = zero;
// Step 1: Build prefix balance frequencies
foreach(char ch in s)
{
// Treat:
// '1' as +1
// '0' as -1
if (ch == '0')
cur--;
else
cur++;
// Invalid prefix state
if (cur <= zero) {
minus++;
}
// Store frequency
mp[cur]++;
}
// Step 2: Count valid substrings
for (int i = 0; i < n; i++) {
// Total substrings - invalid substrings
ans += (n - i - minus);
// If current character is '1'
if (s[i] == '1') {
mp[zero + 1]--;
zero++;
minus += mp[zero];
}
// If current character is '0'
else {
mp[zero - 1]--;
zero--;
minus--;
minus -= mp[zero + 1];
}
}
return ans;
}
static void Main()
{
string s = "110011";
Console.WriteLine(countSubstring(s));
}
}
function countSubstring(s)
{
// Length of string
let n = s.length;
// Final answer
let ans = 0;
// Base index to avoid negative indexing
let zero = n;
// Stores count of invalid prefix states
let minus = 0;
// Frequency array for prefix balances
let mp = new Array(2 * n + 1).fill(0);
// Current prefix balance
let cur = zero;
// Step 1: Build prefix balance frequencies
for (let ch of s) {
// Treat:
// '1' as +1
// '0' as -1
if (ch === "0")
cur--;
else
cur++;
// Invalid prefix state
if (cur <= zero) {
minus++;
}
// Store frequency
mp[cur]++;
}
// Step 2: Count valid substrings
for (let i = 0; i < n; i++) {
// Total substrings - invalid substrings
ans += (n - i - minus);
// If current character is '1'
if (s[i] === "1") {
mp[zero + 1]--;
zero++;
minus += mp[zero];
}
// If current character is '0'
else {
mp[zero - 1]--;
zero--;
minus--;
minus -= mp[zero + 1];
}
}
return ans;
}
// Driver Code
let s = "110011";
console.log(countSubstring(s));
Output
11