Find the number of substrings in a string containing equal numbers of a, b, c

拟墨画扇 提交于 2019-12-13 16:36:46

问题


I'm trying to solve this problem. Now, I was able to get a recursive solution:

If DP[n] gives the number of beautiful substrings (defined in problem) ending at the nth character of the string, then to find DP[n+1], we scan the input string backward from the (n+1)th character until we find an ith character such that the substring beginning at the ith character and ending at the (n+1)th character is beautiful. If no such i can be found, DP[n+1] = 0.

If such a string is found then, DP[n+1] = 1 + DP[i-1].

The trouble is, this solution gives a timeout on one testcase. I suspect it is the scanning backward part that is problematic. The overall time complexity for my solution seems to be O(N^2). The size of the input data seems to indicate that the problem expects an O(NlogN) solution.


回答1:


You don't really need dynamic programming for this; you can do it by iterating over the string once and, after each character, storing the state (the relative number of a's, b's and c's that were encountered so far) in a dictionary. This dictionary has maximum size N+1, so the overall time complexity is O(N).

If you find that at a certain point in the string there are e.g. 5 more a's than b's and 7 more c's than b's, and you find the same situation at another point in the string, then you know that the substring between those two points contains an equal number of a's, b's and c's.

Let's walk through an example with the input "dabdacbdcd":

       a,b,c

   ->  0,0,0  
d  ->  0,0,0  
a  ->  1,0,0  
b  ->  1,1,0  
d  ->  1,1,0  
a  ->  2,1,0  
c  ->  2,1,1  ->  1,0,0  
b  ->  1,1,0  
d  ->  1,1,0  
c  ->  1,1,1  ->  0,0,0    
d  ->  0,0,0  

Because we're only interested in the difference between the number of a's, b'a and c's, not the actual number, we reduce a state like 2,1,1 to 1,0,0 by subtracting the lowest number from all three numbers.

We end up with a dictionary of these states, and the number of times they occur:

0,0,0  ->  4  
1,0,0  ->  2  
1,1,0  ->  4  
2,1,0  ->  1  

States which occur only once don't indicate an abc-equal substring, so we can discard them; we're then left with these repetitions of states:

4, 2, 4  

If a state occurs twice, there is 1 abc-equal substring between those two locations. If a state occurs 4 times, there are 6 abc-equal substrings between them; e.g. the state 1,1,0 occurs at these points:

dab|d|acb|d|cd  

Every substring between 2 of those 4 points is abc-equal:

d, dacb, dacbd, acb, acbd, d  

In general, if a state occurs n times, it represents 1 + 2 + 3 + ... + n-1 abc-equal substrings (or easier to calculate: n-1 × n/2). If we calculate this for every count in the dictionary, the total is our solution:

4  ->  3 x 2 = 6  
2  ->  1 x 1 = 1  
4  ->  3 x 2 = 6  
              --
              13  

Let's check the result by finding what those 13 substrings are:

 1  d---------  
 2  dabdacbdc-  
 3  dabdacbdcd  
 4  -abdacbdc-  
 5  -abdacbdcd  
 6  --bdac----  
 7  ---d------  
 8  ---dacb---  
 9  ---dacbd--  
10  ----acb---  
11  ----acbd--  
12  -------d--  
13  ---------d  


来源:https://stackoverflow.com/questions/47593637/find-the-number-of-substrings-in-a-string-containing-equal-numbers-of-a-b-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!