Given question:
A string of parentheses is said to be
balanced if the left- and right-parentheses in the string can be paired off properly. For example, the strings "(())" and "()()" are both balanced, while the string "(()(" is not
balanced.
Given a string S of length n consisting of parentheses, suppose you want to find the longest subsequence of S that is balanced. Using dynamic programming, design an algorithm that finds the longest balanced subsequence of S in O(n^3) time.
My approach:
Suppose given string: S[1 2 ... n]
A valid sub-sequence can end at S[i] iff S[i] == ')' i.e. S[i] is a closing brace and there exists at least one unused opening brace previous to S[i]. which could be implemented in O(N).
#include<iostream>
using namespace std;
int main(){
string s;
cin >> s;
int n = s.length(), o_count = 0, len = 0;
for(int i=0; i<n; ++i){
if(s[i] == '('){
++o_count;
continue;
}
else if(s[i] == ')' && o_count > 0){
++len;
--o_count;
}
}
cout << len << endl;
return 0;
}
I tried a couple of test cases and they seem to be working fine. Am I missing something here? If not, then how can I also design an O(n^3) Dynamic Programming solution for this problem?
This is the definition of subsequence that I'm using.
Thanks!
For O(n^3)
DP this should work I think:
dp[i, j] = longest balanced subsequence in [i .. j]
dp[i, i] = 0
dp[i, i + 1] = 2 if [i, i + 1] == "()", 0 otherwise
dp[i, j] = max{dp[i, k] + dp[k + 1, j] : j > i + 1} in general
This can be implemented similar to how optimal matrix chain multiplication is.
Your algorithm also seems correct to me, see for example this problem:
http://xorswap.com/questions/107-implement-a-function-to-balance-parentheses-in-a-string-using-the-minimum-nu
Where the solutions are basically the same as yours.
You are only ignoring the extra brackets, so I don't see why it wouldn't work.
Here's a O(n^2)
time and space DP solution in Java:
public int findLongestBalancedSubsequence(String seq, int n) {
int[][] lengths = new int[n][n];
for (int l = 1; l < n; l++) {
for (int i = 0; i < n - l; i++) {
int j = i + l;
// Ends are balanced.
if (seq.charAt(i) == '(' && seq.charAt(j) == ')') {
// lengths[i, j] = max(lengths[i + 1, j - 1] + 2, lengths[i + 1, j] +
// lengths[i, j - 1] - lengths[i + 1, j - 1])
if (lengths[i + 1][j - 1] + 2 > lengths[i + 1][j] +
lengths[i][j - 1] - lengths[i + 1][j - 1])
lengths[i][j] = lengths[i + 1][j - 1] + 2;
else
lengths[i][j] = lengths[i + 1][j] +
lengths[i][j - 1] - lengths[i + 1][j - 1];
// Ends are not balanced.
} else {
// lengths[i, j] = max(lengths[i + 1, j], lengths[i, j - 1])
if (lengths[i + 1][j] > lengths[i][j - 1])
lengths[i][j] = lengths[i + 1][j];
else
lengths[i][j] = lengths[i][j - 1];
}
}
}
return lengths[0][n - 1];
}