5

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!

Community
  • 1
  • 1
srbhkmr
  • 2,074
  • 1
  • 14
  • 19
  • Your program returns 2 for `()()` and 3 for `()()(()`. Both should be 4. – John Kugelman Oct 25 '12 at 17:49
  • @JohnKugelman - why shouldn't the second one be `6`? If his program returns the number of pairs, it returns the correct result for those 2. Multiply by 2 for the actual string length. – IVlad Oct 25 '12 at 17:52
  • @IVlad The balanced parentheses have to be adjacent. – John Kugelman Oct 25 '12 at 17:55
  • @JohnKugelman - I'm not sure what you mean. `()()()` is a balanced subsequence of length 6 (3*2) of `()()(()`. It's also the longest balanced subsequence, and the OP's program correctly finds (half of) its length. – IVlad Oct 25 '12 at 17:57
  • Yes, return value is the no. of pairs in the longest sub-sequence which is properly balanced. – srbhkmr Oct 25 '12 at 18:00
  • Ah, right you are! Items in a subsequence don't need to be adjacent. I assume(d) the problem is to find the longest balanced sub-**string** since the longest sub-sequence is a trivial problem. – John Kugelman Oct 25 '12 at 18:03
  • @srbhkmr Why did you settle for `O(n^3)` solution when the above problem can be solved in `O(n lg n)`. Check this link: http://stackoverflow.com/questions/26643697/longest-subsequence-of-balanced-parentheses or for that matter this question http://codeforces.com/contest/380/problem/C – unrealsoul007 Jul 27 '15 at 13:39

2 Answers2

2

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.

IVlad
  • 43,099
  • 13
  • 111
  • 179
  • Yes, I too think that DP should work. Thanks for that link I thought I was missing something with that approach. – srbhkmr Oct 25 '12 at 18:22
  • 1
    This answer is not correct. consider (()), the algorithm above returns 0 while it must be 4. – Nima Dec 22 '14 at 17:12
  • @Nima - that's correct! You can't apply the same algorithm. In that case, the OP's algorithm should do well. Unfortunately I cannot delete this answer anymore. – IVlad Dec 22 '14 at 21:31
  • 3
    You can find the answer for the generalized version of this question here : http://stackoverflow.com/questions/27583771/grouping-symbols-maximum-length-balanced-subsequent/27584399?noredirect=1#comment43595173_27584399 – Nima Dec 23 '14 at 00:42
1

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];
}
Hardik
  • 21
  • 2
  • Could you give some explanation on `lengths[i, j] = max(lengths[i + 1, j - 1] + 2, lengths[i + 1, j] + lengths[i, j - 1] - lengths[i + 1, j - 1])`. Thanks. – William Nov 28 '17 at 03:24