📌  相关文章
📜  计算具有相同数量的 0、1 和 2 的子串

📅  最后修改于: 2021-10-27 08:36:54             🧑  作者: Mango

给定一个仅由 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 现场工作专业课程学生竞争性编程现场课程