Dada una string binaria s , la tarea es calcular el número de tales substrings donde el conteo de 1 es estrictamente mayor que el conteo de 0 .
Ejemplos
Entrada: S = “110011”
Salida: 11
Explicación: Las
substrings en las que el recuento de 1 es estrictamente mayor que el recuento de 0 son { S[0]}, {S[0], S[1]}, {S[ 0], S[2]}, {S[0], S[4]}, {S[0], S[5]}, {S[1], S[1]}, {S[1] , S[5]}, {S[3], S[5]}, {S[4], S[4]}, {S[4], S[5]}, {S[5], S [5]}.Entrada: S = “101”
Salida: 3
Enfoque ingenuo: el enfoque más simple para resolver el problema es generar todas las substrings y contar el número de 1 y 0 en cada substring. Aumente el conteo de aquellas substrings que contienen el conteo de 1 s mayor que el conteo de 0 s. Finalmente, imprima el conteo obtenido.
Complejidad de Tiempo : O(N 3 )
Espacio Auxiliar: O(1)
Enfoque eficiente: el enfoque anterior se puede optimizar utilizando el algoritmo Merge Sort . Siga los pasos a continuación:
- Inicialice una array, digamos nums[] de tamaño n, donde n es la longitud de la string .
- Atraviesa la cuerda . Si s[i] == ‘1’ , entonces almacene 1 en nums[i] . De lo contrario, establezca nums[i] = -1 .
- Actualice pref[] para almacenar la suma de prefijos de la array nums[] .
- Ahora, el problema se reduce a contar el número de pares (i, j) en el arreglo pref[] , donde pref[i] < pref[j] e i < j , que es similar a contar inversiones en un arreglo desde atrás lado.
- Devuelve el número de inversiones de la array de suma de prefijos como la respuesta final.
A continuación se muestra la implementación del enfoque anterior.
C++14
// C++ program for the above approach #include <bits/stdc++.h> 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.
C#
// C# program of the above approach using System; using System.Collections.Generic; class GFG { // Function to merge two partitions // such that the merged array is sorted static void merge(int[] v, int left, int mid, int right, int inversions) { int[] temp = new int[(right - left + 1)]; int i = left; int j = mid + 1; int k = 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 static void mergeSort(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 static int CountInversions(int[] v) { int n = v.Length; 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 static int getSubsCount(string input) { int n = input.Length; int[] nums = new int[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 int[] pref = new int[n]; int sum = 0; for (int i = 0; i < n; i++) { sum += nums[i]; pref[i] = sum; } int cnt = 1; // Stores the count of valid substrings for (int i = 0; i < n; i++) { if (pref[i] > 0) cnt++; } Array.Sort(pref); Array.Reverse(pref); int inversions = CountInversions(pref); int ans = cnt + inversions; return ans; } // Driver Code public static void Main() { // Given Input string input = "101"; // Function Call int ans = getSubsCount(input); Console.Write(ans); } } // This code is contributed by sanjoy_62.
Javascript
<script> // JavaScript program for the above approach function merge(v, left, mid, right, inversions) { var temp = new Array(right - left + 1).fill(0); var i = left; var j = mid + 1; var k = 0; var cnt = 0; while (i <= mid && j <= right) { if (v[i] <= v[j]) { temp[k] = v[i]; k += 1; i += 1; } else { 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 (var a = left; a <= right; a++) { v[a] = temp[k]; k += 1; } } function mergeSort(v, left, right, inversions) { if (left < right) { var mid = Math.floor((left + right) / 2); mergeSort(v, left, mid, inversions); mergeSort(v, mid + 1, right, inversions); merge(v, left, mid, right, inversions); } } function CountInversions(v) { var n = v.length; var inversions = 0 // Calculate the number of inversions mergeSort(v, 0, n - 1, inversions); return inversions; } function getSubsCount(input) { var n = input.length; var nums = new Array(n).fill(0); for (var i = 0; i < n; i++) { nums[i] = (input[i]).charCodeAt(0) - 48; if (nums[i] == 0) nums[i] = -1; } // Stores the prefix sum array var pref = new Array(n).fill(0); var sum = 0; for (var i = 0; i < n; i++) { sum += nums[i]; pref[i] = sum; } var cnt = 0; // Stores the count of valid substrings for (var i = 0; i < n; i++) { if (pref[i] > 0) cnt += 1; } pref.pop(); var inversions = CountInversions(pref); var ans = cnt + inversions + 1; return ans; } // Driver Code var input = "101"; var ans = getSubsCount(input); document.write(ans); // This code is contributed by phasing17. </script>
Java
// Java program of the above approach import java.util.*; public class GFG { // Function to merge two partitions // such that the merged array is sorted static void merge(int[] v, int left, int mid, int right, int inversions) { int[] temp = new int[(right - left + 1)]; int i = left; int j = mid + 1; int k = 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 static void mergeSort(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 static int CountInversions(int[] v) { int n = v.length; 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 static int getSubsCount(String input) { int n = input.length(); int[] nums = new int[n]; for (int i = 0; i < n; i++) { nums[i] = input.charAt(i) - '0'; if (nums[i] == 0) nums[i] = -1; } // Stores the prefix sum array int[] pref = new int[n]; int sum = 0; for (int i = 0; i < n; i++) { sum += nums[i]; pref[i] = sum; } int cnt = 1; // Stores the count of valid substrings for (int i = 0; i < n; i++) { if (pref[i] > 0) cnt++; } Arrays.sort(pref); Collections.reverse(Arrays.asList(pref)); int inversions = CountInversions(pref); int ans = cnt + inversions; return ans; } // Driver Code public static void main(String[] args) { // Given Input String input = "101"; // Function Call int ans = getSubsCount(input); System.out.println(ans); } } // This code is contributed by phasing17.
3
Complejidad temporal: O(NlogN)
Espacio auxiliar: O(N)