简体   繁体   中英

Binary String Reduction

you are given a binary string (only 0's and 1's) s of length n .
you want to convert s into an empty string by performing the following operation the least number of times.

  • In one Operation, you can remove an alternating subsequence from s without changing the order of the remaining characters.

your task is to determine the minimum number of operations required to convert s into an empty string.

Note:

An alternating subsequence of a string s is defined as follows

  • Any subsequence of length 1
  • if length greater than 1, and no two consecutive elements being equal. For Example, '0101', '101', '0' are alternating sequences, while '100' and '01011' are not.

Constraints:

1 <= T <= 10
1 <= n <= 10^6

Sample Input:

1
10
0100100111

Sample Output:

3

Explanation:

remove subsequence "010101" from " 01 0 01 0 01 11" to make it "0011"

remove subsequence "01" from " 0 01 1 " to make it "01"

finally, remove subsequence "01" from " 01 " to make it "" (empty binary string)

Imagine that for some string x , you know that you can erase it using m operations that end in '0' and n operations that end in '1', for a total of ( m+n ) operations. We will write this (m,n). This is not necessarily the best result, but it is a result.

Now, what do you know about the string x0 ?

If n>1, then you could add a zero to one of those 1-ending operations, turning it into a zero-ending operation, so you could clear x0 in (m+1,n-1) operations.

And of course you could always just add a new 0-ending operation so you could clear x0 in (m+1,n) operations.

Similarly, you could clear x1 in (m,n+1) operations, or (m-1,n+1) if m>0.

Obviously there's only one way to clear the empty string, and that's with (0,0) operations, so working from the start to the end, you can calculate all of the various (m,n) possibilities to clear each prefix until you get to the end, and then the one with the smallest sum is your answer. That would be an O(n 2 ) algorithm.

But, there is no case in which choosing (m+1,n) instead of (m+1,n-1) will enable you to use fewer operations overall. Similarly, there is no case in which choosing (m, n+1) is better than (m-1,n+1).

So, instead of worrying about both possible choices at each position, we can make the single best choice deterministically, depending on whether the next character is 0 or 1:

Starting with x="" and (m,n) = (0,0):

  • When the next char is 0, then x <- x+"0" and (m,n) <- (m+1,max(n-1,0))

  • When the next char is 1, then x <- x+"1" and (m,n) <- (max(m-1,0),n+1)

When you get to the end of the string, m+n is the fewest number of operations that can clear it.

Or, in pseudocode:

m = 0; n = 0;
for (char in string) {
    if (char == 0') {
        m = m+1;
        n = max(n-1,0);
    } else {
        m = max(m-1,0);
        n = n+1;
    }
}
return m+n;

Easy peasy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM