You are given two 0-indexed binary strings s1
and s2
, both of length n
, and a positive integer x
.
You can perform any of the following operations on the string s1
any number of times:
- Choose two indices
i
andj
, and flip boths1[i]
ands1[j]
. The cost of this operation isx
. - Choose an index
i
such thati < n - 1
and flip boths1[i]
ands1[i + 1]
. The cost of this operation is1
.
Return the minimum cost needed to make the strings s1
and s2
equal, or return -1
if it is impossible.
Note that flipping a character means changing it from 0
to 1
or vice-versa.
Example 1:
Input: s1 = "1100011000", s2 = "0101001010", x = 2
Output: 4
Explanation: We can do the following operations:
- Choose i = 3 and apply the second operation. The resulting string is s1 = "1101111000".
- Choose i = 4 and apply the second operation. The resulting string is s1 = "1101001000".
- Choose i = 0 and j = 8 and apply the first operation. The resulting string is s1 = "0101001010" = s2.
The total cost is 1 + 1 + 2 = 4. It can be shown that it is the minimum cost possible.
Example 2:
Input: s1 = "10110", s2 = "00011", x = 4
Output: -1
Explanation: It is not possible to make the two strings equal.
Constraints:
n == s1.length == s2.length
1 <= n, x <= 500
s1
ands2
consist only of the characters'0'
and'1'
.
Problem Analysis:
There are two operations, flip two neighbouring items, the cost is 1, otherwise flip two items, the cost is x. So we need to differentiate them.
Here we use the finite state algorithm. We iterate compute prefix strings from 1 to n length. According to the flip operations, we can only check the different positions of the two strings.
We need to record several state, assume done means the min cost of current prefix strings, last means the min cost but the last index is different, one means 1 position in the prefix strings is different but not the last index, two means 2 position in the prefix strings is different, and 1 of these is in the last index.
So when we add 1 length at the end of the prefix strings, we can update the states, assume the index is i, if s1[i] = s2[i]:
- last = last + 1, we flip the i-1 and i
- two = two + 1, we flip the i-1 and i
if s1[i] != s2[i]:
- done = min(one + x, last + 1), the min cost is small one that changes one or last state to done state
- two = one
- one = min(done, two + 1), the min cost is small one that changes done or two state to one state
- last = min(done, two + x), the min cost is the small one that changes done or two state to last state
Note done, two states and one, last states can not exist in the same time. The trick here is we can check done state is valid with done < s1.size().
Finally, the done value is the answer.
Solution
class Solution {
public:
int minOperations(string s1, string s2, int x) {
int done{0};
int inf = 1e6;
int one{inf};
int last{inf};
int two{inf};
for (int i = 0; i < s1.size(); ++i) {
if (s1[i] == s2[i]) {
++last;
++two;
} else if (done < s1.size()) {
one = min(done, two + 1);
last = min(done, two + x);
done = two = inf;
} else {
done = min(one + x, last + 1);
two = one;
one = last = inf;
}
}
return done < inf ? done : -1;
}
};
Time complexity is O(n)
Space complexity is O(1)