在给定的二进制字符串中具有相等比率的 0 和 1 直到第 i 个索引的子字符串的计数
给定一个二进制字符串S ,任务是打印从开始到第i 个索引的0和1比率相等的子字符串的最大数量。
例子:
Input: S = “110001”
Output: {1, 2, 1, 1, 1, 2}
Explanation: The given string can be partitioned into the following equal substrings:
- Valid substrings upto index 0 : “1”, possible no. of substrings = 1
- Valid substrings upto index 1 : “1”, “B”, possible no. of substrings = 2
- Valid substrings upto index 2 : “110”, possible no. of substrings = 1
- Valid substrings upto index 3 : “1100”, possible no. of substrings = 1
- Valid substrings upto index 4 : “11000”, possible no. of substrings = 1
- Valid substrings upto index 5 : “1100”, “01”, possible no. of substrings = 2
Input: S = “010100001”
Output: {1, 1, 1, 2, 1, 2, 1, 1, 3}
方法:可以使用数学概念和 HashMap 来存储对的频率来解决该任务按照以下步骤解决问题:
- 为出现的0和1创建两个前缀数组,分别表示pre0[]和pre1[] 。
- 对于每个前缀,用一对 (a, b) 对其进行标记,其中 a = 此前缀中“0”的频率,b = “1”的频率。 a 和 b 除以 gcd(a, b) 得到最简单的形式。
- 遍历所有prefixes ,并将前缀的答案存储为该对的当前出现次数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to retuan a prefix array of
// equal partitions of the given string
// consisting of 0s and 1s
void equalSubstrings(string s)
{
// Length of the string
int n = s.size();
// Prefix arrays for 0s and 1s
int pre0[n] = { 0 }, pre1[n] = { 0 };
// If character at index 0 is 0
if (s[0] == '0') {
pre0[0] = 1;
}
// If character at index 0 is 1
else {
pre1[0] = 1;
}
// Filling the prefix arrays
for (int i = 1; i < n; i++) {
if (s[i] == '0') {
pre0[i] = pre0[i - 1] + 1;
pre1[i] = pre1[i - 1];
}
else {
pre0[i] = pre0[i - 1];
pre1[i] = pre1[i - 1] + 1;
}
}
// Vector to store the answer
vector ans;
// Map to store the ratio
map, int> mp;
for (int i = 0; i < n; i++) {
// Find the gcd of pre0[i] and pre1[i]
int x = __gcd(pre0[i], pre1[i]);
// Converting the elements in
// simplest form
int l = pre0[i] / x, r = pre1[i] / x;
// Update the value in map
mp[{ l, r }]++;
// Store this in ans
ans.push_back(mp[{ l, r }]);
}
// Return the ans vector
for (auto i : ans)
cout << i << " ";
}
// Driver Code
int main()
{
string s = "001110";
equalSubstrings(s);
return 0;
}
Java
// Java program for the above approach
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
class GFG
{
// Function to retuan a prefix array of
// equal partitions of the given string
// consisting of 0s and 1s
public static void equalSubstrings(String s)
{
// Length of the string
int n = s.length();
// Prefix arrays for 0s and 1s
int[] pre0 = new int[n];
int[] pre1 = new int[n];
Arrays.fill(pre0, 0);
Arrays.fill(pre1, 0);
// If character at index 0 is 0
if (s.charAt(0) == '0') {
pre0[0] = 1;
}
// If character at index 0 is 1
else {
pre1[0] = 1;
}
// Filling the prefix arrays
for (int i = 1; i < n; i++) {
if (s.charAt(i) == '0') {
pre0[i] = pre0[i - 1] + 1;
pre1[i] = pre1[i - 1];
} else {
pre0[i] = pre0[i - 1];
pre1[i] = pre1[i - 1] + 1;
}
}
// Vector to store the answer
ArrayList ans = new ArrayList();
// Map to store the ratio
HashMap mp = new HashMap();
for (int i = 0; i < n; i++)
{
// Find the gcd of pre0[i] and pre1[i]
int x = __gcd(pre0[i], pre1[i]);
// Converting the elements in
// simplest form
int l = pre0[i] / x, r = pre1[i] / x;
String key = l + "," + r;
// Update the value in map
if (mp.containsKey(key))
mp.put(key, mp.get(key) + 1);
else
mp.put(key, 1);
// Store this in ans
ans.add(mp.get(key));
}
// Return the ans vector
for (int i : ans)
System.out.print(i + " ");
}
public static int __gcd(int a, int b) {
if (b == 0)
return a;
return __gcd(b, a % b);
}
// Driver Code
public static void main(String args[]) {
String s = "001110";
equalSubstrings(s);
}
}
// This code is contributed by gfgking.
Python3
# Python program for the above approach
def __gcd(a, b):
if (b == 0):
return a
return __gcd(b, a % b)
# Function to retuan a prefix array of
# equal partitions of the given string
# consisting of 0s and 1s
def equalSubstrings(s):
# Length of the string
n = len(s)
# Prefix arrays for 0s and 1s
pre0 = [0] * n
pre1 = [0] * n
# If character at index 0 is 0
if (s[0] == '0'):
pre0[0] = 1
# If character at index 0 is 1
else:
pre1[0] = 1
# Filling the prefix arrays
for i in range(1, n):
if (s[i] == '0'):
pre0[i] = pre0[i - 1] + 1
pre1[i] = pre1[i - 1]
else:
pre0[i] = pre0[i - 1]
pre1[i] = pre1[i - 1] + 1
# Vector to store the answer
ans = []
# Map to store the ratio
mp = {}
for i in range(n):
# Find the gcd of pre0[i] and pre1[i]
x = __gcd(pre0[i], pre1[i])
# Converting the elements in
# simplest form
l = pre0[i] // x
r = pre1[i] // x
# Update the value in map
if (f'[{l}, {r}]' in mp):
mp[f'[{l}, {r}]'] += 1
else:
mp[f'[{l}, {r}]'] = 1
# Store this in ans
ans.append(mp[f'[{l}, {r}]'])
# Return the ans vector
for i in ans:
print(i, end=" ")
# Driver Code
s = "001110"
equalSubstrings(s)
# This code is contributed by gfgking
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to retuan a prefix array of
// equal partitions of the given string
// consisting of 0s and 1s
public static void equalSubstrings(string s)
{
// Length of the string
int n = s.Length;
// Prefix arrays for 0s and 1s
int[] pre0 = new int[n];
int[] pre1 = new int[n];
// Arrays.fill(pre0, 0);
// Arrays.fill(pre1, 0);
// If character at index 0 is 0
if (s[0] == '0') {
pre0[0] = 1;
}
// If character at index 0 is 1
else {
pre1[0] = 1;
}
// Filling the prefix arrays
for (int i = 1; i < n; i++) {
if (s[i] == '0') {
pre0[i] = pre0[i - 1] + 1;
pre1[i] = pre1[i - 1];
}
else {
pre0[i] = pre0[i - 1];
pre1[i] = pre1[i - 1] + 1;
}
}
// Vector to store the answer
List ans = new List();
// Map to store the ratio
Dictionary mp
= new Dictionary();
for (int i = 0; i < n; i++) {
// Find the gcd of pre0[i] and pre1[i]
int x = __gcd(pre0[i], pre1[i]);
// Converting the elements in
// simplest form
int l = pre0[i] / x, r = pre1[i] / x;
string key = l + "," + r;
// Update the value in map
if (mp.ContainsKey(key))
mp[key] += 1;
else
mp[key] = 1;
// Store this in ans
ans.Add(mp[key]);
}
// Return the ans vector
foreach(int i in ans) Console.Write(i + " ");
}
public static int __gcd(int a, int b)
{
if (b == 0)
return a;
return __gcd(b, a % b);
}
// Driver Code
public static void Main(string[] args)
{
string s = "001110";
equalSubstrings(s);
}
}
// This code is contributed by ukasp.
Javascript
输出
1 2 1 1 1 2
时间复杂度: O(nlogn)
辅助空间: O(n)