Nice question!
Here is the problem in more popular terms.
Balanced Parentheses
A string of parentheses is balanced if we can change it to the empty string by removing substrings "()" repeatedly. For example, empty string, "()" and "(())()((()()))" are balanced but none of "())" and ")()()(" is balanced.
It is clear that a balanced string must start with "(" and ending with ")". It must be of even length as well.
the Problem of Minimum Operations to Balance a String
Let s
be a non-empty string of parentheses of length n
. The only operation we can perform is flipping every parenthesis in a substring, that is, changing every "(" to ")" and every ")" to "(" for some contiguous characters in the string. The problem is how to find the smallest number of operations that make s
balanced.
an Approach by Dynamic Programming
What are the appropriate subproblems? They are dp[i][j]
for 0 <= i < j < n
, where dp[i][j]
is the minimum number of operations that balance the substring between indice i
and index j
inclusive. The wanted minimum number of operations that balance s
is dp[0][n-1]
.
Since any string of odd length cannot be balanced, we will restrict our attention to strings of even length from now on.
the base cases
dp[i][i+1]
is 0 if the substring between i
and i+1
is balanced, i.e, "()". It is 1 otherwise.
the recurrence relation
I will use Java to define the recurrence relation.
void dp(int i, int j) {
assert 0 <=i && i + 2 < j && j <= L;
int min = dp[i + 1][j - 1];
if (s.charAt(i) == ')' && s.charAt(i + 1) == '(') min++;
if (s.charAt(j) == '(' && s.charAt(j - 1) == ')') min++;
for (int k = i + 1; k < j - 1; k+=2) {
if (a[k] == 1 && a[k + 1] == -1) {
if (min > dp[i][k] + dp[k + 1][j] - 1) {
min = dp[i][k] + dp[k + 1][j] - 1;
}
} else {
if (min > dp[i][k] + dp[k + 1][j]) {
min = dp[i][k] + dp[k + 1][j];
}
}
}
dp[i][j] = min;
}
The recurrence relation comes from the following well-known property of balanced strings. A non-empty string is balanced if and only if it is the concatenation of two balanced strings or "(" followed by a balanced string followed by ")".
The processing before the for
loop, which sets min
to be dp[i + 1][j - 1]
plus 0, 1 or 2, comes from the fact that "(" followed by a balanced string followed by ")" must be a balanced string.
The processing in the for
loop, which tries to shrink min
to dp[i][k] + dp[k + 1][j]
minus 0 or 1 for some k
that is between i
and j
, comes from the fact that the concatenation of two balanced strings must be a balanced string.
The time-complexity of this approach is $O(n^3)$. The space-complexity is $O(n^2)$.
Length of the "most unbalanced" strings
The smallest length of a string that cannot be balanced by less than 2 operations is 4. For example, ")((("
The smallest length of a string that cannot be balanced by less than 3 operations is 10. For example, ")(((((())("
The smallest length of a string that cannot be balanced by less than 4 operations is 22. For example, ")(())))(((((((((((())(".
Question: What is the smallest length of a string that needs at least 5 operations? As I have computed, it must be greater than 28. However, my computation is not enough to determine the actual value. How fast can we compute these smallest lengths?