给定一个仅由 0、1 或 2 组成的字符串,计算具有相同数量 0、1 和 2 的子串的数量。
例子:
Input : str = “0102010”
Output : 2
Explanation : Substring str[2, 4] = “102” and
substring str[4, 6] = “201” has
equal number of 0, 1 and 2
Input : str = "102100211"
Output : 5
一个简单的解决方案是遍历 str 的所有子字符串并检查它们是否包含相等的 0,1 和 2。 str 的子串总数为 O(n 2 ) 检查每个子串的计数需要 O(n) 次,因此使用蛮力方法解决此问题所需的总时间为 O(n 3 ) 时间。
一个有效的解决方案是跟踪 0、1 和 2 的计数。
Let zc[i] denotes number of zeros between index 1 and i
oc[i] denotes number of ones between index 1 and i
tc[i] denotes number of twos between index 1 and i
for substring str[i, j] to be counted in result we should have :
zc[i] – zc[j-1] = oc[i] – oc[j-1] = tc[i] - tc[j-1]
we can write above relation as follows :
z[i] – o[i] = z[j-1] – o[j-1] and
z[i] – t[i] = z[j-1] – t[j-1]
在字符串循环时可以跟踪上述关系,在每个索引处,我们将计算这个差异对,我们将检查这个差异对之前发生了多少次,我们将该计数添加到我们的结果中,以进行跟踪我们在下面的代码中使用了之前的差异对的映射。考虑到映射操作(如搜索和插入)花费 O(Log n) 时间这一事实,该解决方案的总时间复杂度为 O(n log n)。
C++
// C++ program to find substring with equal
// number of 0's, 1's and 2's
#include
using namespace std;
// Method to count number of substring which
// has equal 0, 1 and 2
int getSubstringWithEqual012(string str)
{
int n = str.length();
// map to store, how many times a difference
// pair has occurred previously
map< pair, int > mp;
mp[make_pair(0, 0)] = 1;
// zc (Count of zeroes), oc(Count of 1s)
// and tc(count of twos)
// In starting all counts are zero
int zc = 0, oc = 0, tc = 0;
// looping into string
int res = 0; // Initialize result
for (int i = 0; i < n; ++i)
{
// increasing the count of current character
if (str[i] == '0') zc++;
else if (str[i] == '1') oc++;
else tc++; // Assuming that string doesn't contain
// other characters
// making pair of differences (z[i] - o[i],
// z[i] - t[i])
pair tmp = make_pair(zc - oc,
zc - tc);
// Count of previous occurrences of above pair
// indicates that the subarrays forming from
// every previous occurrence to this occurrence
// is a subarray with equal number of 0's, 1's
// and 2's
res = res + mp[tmp];
// increasing the count of current difference
// pair by 1
mp[tmp]++;
}
return res;
}
// driver code to test above method
int main()
{
string str = "0102010";
cout << getSubstringWithEqual012(str) << endl;
return 0;
}
Java
// Java program to find substring with equal
// number of 0's, 1's and 2's
import java.io.*;
import java.util.*;
class GFG {
// Method to count number of substring which
// has equal 0, 1 and 2
private static int getSubstringWithEqual012(String str)
{
// map to store, how many times a difference
// pair has occurred previously (key = diff1 *
// diff2)
HashMap map = new HashMap<>();
map.put("0*0", 1);
// zc (Count of zeroes), oc(Count of 1s)
// and tc(count of twos)
// In starting all counts are zero
int zc = 0, oc = 0, tc = 0;
int ans = 0;
// looping into string
for (int i = 0; i < str.length(); i++) {
// increasing the count of current character
if (str.charAt(i) == '0')
zc++;
else if (str.charAt(i) == '1')
oc++;
else
tc++;
// making key of differences (z[i] - o[i],
// z[i] - t[i])
String key = (zc - oc) + "*" + (zc - tc);
// Count of previous occurrences of above pair
// indicates that the subarrays forming from
// every previous occurrence to this occurrence
// is a subarray with equal number of 0's, 1's
// and 2's
ans += map.getOrDefault(key, 0);
map.put(key, map.getOrDefault(key, 0) + 1);
}
// increasing the count of current difference
// pair by 1
return ans;
}
// Driver Code
public static void main(String[] args)
{
// Input
String str = "0102010";
System.out.println(getSubstringWithEqual012(str));
}
}
Python3
# Python3 program to find substring with equal
# number of 0's, 1's and 2's
# Method to count number of substring which
# has equal 0, 1 and 2
def getSubstringWithEqual012(string):
n = len(string)
# map to store, how many times a difference
# pair has occurred previously
mp = dict()
mp[(0, 0)] = 1
# zc (Count of zeroes), oc(Count of 1s)
# and tc(count of twos)
# In starting all counts are zero
zc, oc, tc = 0, 0, 0
# looping into string
res = 0 # Initialize result
for i in range(n):
# increasing the count of current character
if string[i] == '0':
zc += 1
elif string[i] == '1':
oc += 1
else:
tc += 1 # Assuming that string doesn't contain
# other characters
# making pair of differences (z[i] - o[i],
# z[i] - t[i])
tmp = (zc - oc, zc - tc)
# Count of previous occurrences of above pair
# indicates that the subarrays forming from
# every previous occurrence to this occurrence
# is a subarray with equal number of 0's, 1's
# and 2's
if tmp not in mp:
res += 0
else:
res += mp[tmp]
# increasing the count of current difference
# pair by 1
if tmp in mp:
mp[tmp] += 1
else:
mp[tmp] = 1
return res
# Driver Code
if __name__ == "__main__":
string = "0102010"
print(getSubstringWithEqual012(string))
# This code is contributed by
# sanjeev2552
输出:
2
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。