Related Articles

# Count of substrings in a Binary String that contains more 1s than 0s

• Last Updated : 21 Jul, 2021

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 { S}, {S, S}, {S, S}, {S, S}, {S, S}, {S, S}, {S, S}, {S, S}, {S, S}, {S, S}, {S, S}.

Input: S = “101”
Output: 3

Naive Approach: 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.
Time Complexity: O(N3)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized using Merge Sort Algorithm. Follow the steps below:

• Initialize an array, say nums[] of size n, where n is the length of the string.
• Traverse the string. If s[i]  == ‘1’, then store 1 in nums[i]. Otherwise, set nums[i] = -1.
• Update pref[] to store prefix sum of the array nums[].
• Now, the problem reduces to counting the number of pairs(i, j) in the array pref[], where pref[i] < pref[j] and i < j, which is similar to counting inversions in an array from the rear side.
• Return the number of inversions of the prefix sum array as the final answer.

Below is the implementation of the above approach.

## C++14

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to merge two partitions``// such that the merged array is sorted``void` `merge(vector<``int``>& v, ``int` `left,``           ``int` `mid, ``int` `right, ``int``& inversions)``{``    ``vector<``int``> temp(right - left + 1);` `    ``int` `i = left;``    ``int` `j = mid + 1;``    ``int` `k = 0;``    ``int` `cnt = 0;` `    ``while` `(i <= mid && j <= right) {``        ``if` `(v[i] <= v[j]) {``            ``temp[k++] = v[i++];``        ``}``        ``else` `{``            ``// Counting inversions``            ``inversions += (mid - i + 1);` `            ``temp[k++] = v[j++];``        ``}``    ``}` `    ``while` `(i <= mid)``        ``temp[k++] = v[i++];` `    ``while` `(j <= right)``        ``temp[k++] = v[j++];` `    ``k = 0;``    ``for` `(``int` `a = left; a <= right; a++) {``        ``v[a] = temp[k++];``    ``}``}` `// Function to implement merge sort``void` `mergeSort(vector<``int``>& v, ``int` `left,``               ``int` `right, ``int``& inversions)``{``    ``if` `(left < right) {``        ``int` `mid = (left + right) / 2;` `        ``mergeSort(v, left, mid, inversions);``        ``mergeSort(v, mid + 1, right, inversions);``        ``merge(v, left, mid, right, inversions);``    ``}``}` `// Function to calculate number of``// inversions in a given array``int` `CountInversions(vector<``int``>& v)``{``    ``int` `n = v.size();``    ``int` `inversions = 0;` `    ``// Calculate the number of inversions``    ``mergeSort(v, 0, n - 1, inversions);` `    ``// Return the number of inversions``    ``return` `inversions;``}` `// Function to count the number of``// substrings that contains more 1s than 0s``int` `getSubsCount(string& input)``{``    ``int` `n = input.length();` `    ``vector<``int``> nums(n);` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``nums[i] = input[i] - ``'0'``;` `        ``if` `(nums[i] == 0)``            ``nums[i] = -1;``    ``}` `    ``// Stores the prefix sum array``    ``vector<``int``> pref(n);` `    ``int` `sum = 0;` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``sum += nums[i];``        ``pref[i] = sum;``    ``}` `    ``int` `cnt = 0;` `    ``// Stores the count of valid substrings``    ``for` `(``int` `i = 0; i < n; i++) {``        ``if` `(pref[i] > 0)``            ``cnt++;``    ``}` `    ``reverse(pref.begin(), pref.end());` `    ``int` `inversions = CountInversions(pref);` `    ``int` `ans = cnt + inversions;` `    ``return` `ans;``}` `// Driver Code``int` `main()``{` `    ``// Given Input``    ``string input = ``"101"``;` `    ``// Function Call``    ``int` `ans = getSubsCount(input);` `    ``cout << ans << endl;` `    ``return` `0;``}`

## Python3

 `# python 3 program for the above approach` `# Function to merge two partitions``# such that the merged array is sorted``def` `merge(v, left,mid, right, inversions):``    ``temp ``=` `[``0` `for` `i ``in` `range``(right ``-` `left ``+` `1``)]` `    ``i ``=` `left``    ``j ``=` `mid ``+` `1``    ``k ``=` `0``    ``cnt ``=` `0` `    ``while` `(i <``=` `mid ``and` `j <``=` `right):``        ``if` `(v[i] <``=` `v[j]):``            ``temp[k] ``=` `v[i]``            ``k ``+``=` `1``            ``i ``+``=` `1` `        ``else``:``            ``# Counting inversions``            ``inversions ``+``=` `(mid ``-` `i ``+` `1``)` `            ``temp[k] ``=` `v[j]``            ``k ``+``=` `1``            ``j ``+``=` `1` `    ``while` `(i <``=` `mid):``        ``temp[k] ``=` `v[i]``        ``k ``+``=` `1``        ``i ``+``=` `1` `    ``while` `(j <``=` `right):``        ``temp[k] ``=` `v[j]``        ``k ``+``=` `1``        ``j ``+``=` `1` `    ``k ``=` `0``    ``for` `a ``in` `range``(left,right``+``1``,``1``):``        ``v[a] ``=` `temp[k]``        ``k ``+``=` `1` `# Function to implement merge sort``def` `mergeSort(v, left, right,inversions):``    ``if` `(left < right):``        ``mid ``=` `(left ``+` `right) ``/``/` `2` `        ``mergeSort(v, left, mid, inversions)``        ``mergeSort(v, mid ``+` `1``, right, inversions)``        ``merge(v, left, mid, right, inversions)` `# Function to calculate number of``# inversions in a given array``def` `CountInversions(v):``    ``n ``=` `len``(v)``    ``inversions ``=` `0` `    ``# Calculate the number of inversions``    ``mergeSort(v, ``0``, n ``-` `1``, inversions)` `    ``# Return the number of inversions``    ``return` `inversions` `# Function to count the number of``# substrings that contains more 1s than 0s``def` `getSubsCount(``input``):``    ``n ``=` `len``(``input``)` `    ``nums ``=` `[``0` `for` `i ``in` `range``(n)]` `    ``for` `i ``in` `range``(n):``        ``nums[i] ``=` `ord``(``input``[i]) ``-` `48` `        ``if` `(nums[i] ``=``=` `0``):``            ``nums[i] ``=` `-``1` `    ``# Stores the prefix sum array``    ``pref ``=` `[``0` `for` `i ``in` `range``(n)]` `    ``sum` `=` `0` `    ``for` `i ``in` `range``(n):``        ``sum` `+``=` `nums[i]``        ``pref[i] ``=` `sum` `    ``cnt ``=` `0` `    ``# Stores the count of valid substrings``    ``for` `i ``in` `range``(n):``        ``if` `(pref[i] > ``0``):``            ``cnt ``+``=` `1``    ` `    ``pref ``=` `pref[:``-``1``]` `    ``inversions ``=` `CountInversions(pref)` `    ``ans ``=` `cnt ``+` `inversions ``+` `1` `    ``return` `ans` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``  ` `    ``# Given Input``    ``input` `=` `"101"` `    ``# Function Call``    ``ans ``=` `getSubsCount(``input``)``    ``print``(ans)``    ` `    ``# This code is contributed by ipg2016107.`

Output:
`3`

Time Complexity: O(NlogN)
Auxiliary Space: O(N) My Personal Notes arrow_drop_up