📌  相关文章
📜  最长平衡子序列的长度

📅  最后修改于: 2021-04-29 18:18:37             🧑  作者: Mango

给定字符串S ,找到其中最长的平衡子序列的长度。平衡的字符串定义为:

  • 空字符串是平衡字符串。
  • 如果X和Y是平衡字符串,则(X)Y和XY是平衡字符串。

例子 :

Input : S = "()())"
Output : 4

()() is the longest balanced subsequence 
of length 4.

Input : s = "()(((((()"
Output : 4

方法1:蛮力方法是查找给定字符串S的所有子序列,并检查所有可能的子序列是否形成平衡序列,如果是,则将其与最大值进行比较。

更好的方法是使用动态编程。

最长平衡子序列(LBS)可以递归定义如下。

LBS of substring str[i..j] : 
If str[i] == str[j]
    LBS(str, i, j) = LBS(str, i + 1, j - 1) + 2
Else
    LBS(str, i, j) = max(LBS(str, i, k) +
                         LBS(str, k + 1, j))
                     Where i <= k < j   

声明2D矩阵dp [] [],其中我们的状态dp [i] [j]表示从索引i到j的最长平衡子序列的长度。我们将按递增j – i的顺序计算此状态。对于特定状态dp [i] [j],我们将尝试将第j个符号与第k个符号进行匹配,只有在S [k]为’(’并且S [j]为’)’时才能这样做。对于所有可能的k取最大值2 + dp [i] [k – 1] + dp [k + 1] [j – 1],还取max(dp [i + 1] [j],dp [i] [j – 1])并将值放在dp [i] [j]中。这样,我们可以填充所有dp状态。 dp [0] [字符串的长度– 1](考虑0索引)将是我们的答案。

以下是此方法的实现:

C++
// C++ program to find length of
// the longest balanced subsequence
#include 
using namespace std;
  
int maxLength(char s[], int n)
{
    int dp[n][n];
    memset(dp, 0, sizeof(dp));
  
    // Considering all balanced
    // substrings of length 2
    for (int i = 0; i < n - 1; i++)
        if (s[i] == '(' && s[i + 1] == ')')
            dp[i][i + 1] = 2;
  
    // Considering all other substrings
    for (int l = 2; l < n; l++) {
        for (int i = 0, j = l; j < n; i++, j++) {
            if (s[i] == '(' && s[j] == ')')
                dp[i][j] = 2 + dp[i + 1][j - 1];
  
            for (int k = i; k < j; k++)
                dp[i][j] = max(dp[i][j],
                               dp[i][k] + dp[k + 1][j]);
        }
    }
  
    return dp[0][n - 1];
}
  
// Driver Code
int main()
{
    char s[] = "()(((((()";
    int n = strlen(s);
    cout << maxLength(s, n) << endl;
    return 0;
}


Java
// Java program to find length of the
// longest balanced subsequence.
import java.io.*;
  
class GFG {
    static int maxLength(String s, int n)
    {
        int dp[][] = new int[n][n];
  
        // Considering all balanced substrings
        // of length 2
        for (int i = 0; i < n - 1; i++)
            if (s.charAt(i) == '(' && s.charAt(i + 1) == ')')
                dp[i][i + 1] = 2;
  
        // Considering all other substrings
        for (int l = 2; l < n; l++) {
            for (int i = 0, j = l; j < n; i++, j++) {
                if (s.charAt(i) == '(' && s.charAt(j) == ')')
                    dp[i][j] = 2 + dp[i + 1][j - 1];
  
                for (int k = i; k < j; k++)
                    dp[i][j] = Math.max(dp[i][j],
                                        dp[i][k] + dp[k + 1][j]);
            }
        }
  
        return dp[0][n - 1];
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String s = "()(((((()";
        int n = s.length();
        System.out.println(maxLength(s, n));
    }
}
// This code is contributed by Prerna Saini


Python3
# Python3 program to find length of 
# the longest balanced subsequence 
  
def maxLength(s, n):
      
    dp = [[0 for i in range(n)]
             for i in range(n)]
               
    # Considering all balanced 
    # substrings of length 2 
    for i in range(n - 1): 
        if (s[i] == '(' and s[i + 1] == ')'): 
            dp[i][i + 1] = 2
  
    # Considering all other substrings 
    for l in range(2, n):
        i = -1
        for j in range(l, n):
            i += 1
            if (s[i] == '(' and s[j] == ')'): 
                dp[i][j] = 2 + dp[i + 1][j - 1] 
            for k in range(i, j): 
                dp[i][j] = max(dp[i][j], dp[i][k] +
                                         dp[k + 1][j])
    return dp[0][n - 1] 
  
# Driver Code 
s = "()(((((()"
n = len(s)
print(maxLength(s, n)) 
  
# This code is contributed 
# by sahishelangia


C#
// C# program to find length of the
// longest balanced subsequence.
using System;
  
class GFG {
  
    static int maxLength(String s, int n)
    {
        int[, ] dp = new int[n, n];
  
        // Considering all balanced substrings
        // of length 2
        for (int i = 0; i < n - 1; i++)
            if (s[i] == '(' && s[i + 1] == ')')
                dp[i, i + 1] = 2;
  
        // Considering all other substrings
        for (int l = 2; l < n; l++) {
            for (int i = 0, j = l; j < n; i++, j++) {
                if (s[i] == '(' && s[j] == ')')
                    dp[i, j] = 2 + dp[i + 1, j - 1];
  
                for (int k = i; k < j; k++)
                    dp[i, j] = Math.Max(dp[i, j],
                                        dp[i, k] + dp[k + 1, j]);
            }
        }
  
        return dp[0, n - 1];
    }
  
    // Driver Code
    public static void Main()
    {
        string s = "()(((((()";
        int n = s.Length;
        Console.WriteLine(maxLength(s, n));
    }
}
  
// This code is contributed by vt_m.


PHP


C++
// C++ program to find length of
// the longest balanced subsequence
#include 
using namespace std;
  
int maxLength(char s[], int n)
{
    // As it's subsequence - assuming first
    // open brace would map to a first close
    // brace which occurs after the open brace
    // to make subsequence balanced and second
    // open brace would map to second close
    // brace and so on.
  
    // Variable to count all the open brace
    // that does not have the corresponding
    // closing brace.
    int invalidOpenBraces = 0;
  
    // To count all the close brace that
    // does not have the corresponding open brace.
    int invalidCloseBraces = 0;
  
    // Iterating over the String
    for (int i = 0; i < n; i++) {
        if (s[i] == '(') {
  
            // Number of open braces that
            // hasn't been closed yet.
            invalidOpenBraces++;
        }
        else {
            if (invalidOpenBraces == 0) {
  
                // Number of close braces that
                // cannot be mapped to any open
                // brace.
                invalidCloseBraces++;
            }
            else {
  
                // Mapping the ith close brace
                // to one of the open brace.
                invalidOpenBraces--;
            }
        }
    }
    return (
        n - (invalidOpenBraces
             + invalidCloseBraces));
}
  
// Driver Code
int main()
{
    char s[] = "()(((((()";
    int n = strlen(s);
    cout << maxLength(s, n) << endl;
    return 0;
}


Java
// Java program to find the length of the
// longest balanced subsequence.
import java.io.*;
  
class GFG {
    static int maxLength(String s, int n)
    {
        // As it's subsequence - assuming first
        // open brace would map to a first close
        // brace which occurs after the open brace
        // to make subsequence balanced and second
        // open brace would map to second close
        // brace and so on.
  
        // Variable to count all the open brace
        // that does not have the corresponding
        // closing brace.
        int invalidOpenBraces = 0;
  
        // To count all the close brace that
        // does not have the corresponding open brace.
        int invalidCloseBraces = 0;
  
        // Iterating over the String
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '(') {
  
                // Number of open braces that
                // hasn't been closed yet.vvvvvv
                invalidOpenBraces++;
            }
            else {
                if (invalidOpenBraces == 0) {
  
                    // Number of close braces that
                    // cannot be mapped to any open
                    // brace.
                    invalidCloseBraces++;
                }
                else {
  
                    // Mapping the ith close brace
                    // to one of the open brace.
                    invalidOpenBraces--;
                }
            }
        }
        return (
            n - (invalidOpenBraces
                 + invalidCloseBraces));
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String s = "()(((((()";
        int n = s.length();
        System.out.println(maxLength(s, n));
    }
}


Python3
# Python3 program to find length of 
# the longest balanced subsequence 
  
def maxLength(s, n):
              
    # As it's subsequence - assuming first
    # open brace would map to a first close
    # brace which occurs after the open brace
    # to make subsequence balanced and second
    # open brace would map to second close 
    # brace and so on.
      
    # Variable to count all the open brace 
    # that does not have the corresponding 
    # closing brace. 
    invalidOpenBraces = 0;
  
    # To count all the close brace that does
    # not have the corresponding open brace.
    invalidCloseBraces = 0;
      
    # Iterating over the String
    for i in range(n):
        if( s[i] == '(' ):
                  
                # Number of open braces that 
                # hasn't been closed yet.
                invalidOpenBraces += 1
        else:
            if(invalidOpenBraces == 0):
                # Number of close braces that
                # cannot be mapped to any open
                # brace.
                invalidCloseBraces += 1
            else:
                # Mapping the ith close brace
                # to one of the open brace.
                invalidOpenBraces -= 1
  
    return (
n - (
invalidOpenBraces + invalidCloseBraces)) 
  
# Driver Code 
s = "()(((((()"
n = len(s)
print(maxLength(s, n))


C#
// C# program to find length of the
// longest balanced subsequence.
using System;
  
class GFG {
  
    static int maxLength(String s, int n)
    {
  
        // As it's subsequence - assuming first
        // open brace would map to a first close
        // brace which occurs after the open brace
        // to make subsequence balanced and second
        // open brace would map to second close
        // brace and so on.
  
        // Variable to count all the open brace
        // that does not have the corresponding
        // closing brace.
        int invalidOpenBraces = 0;
  
        // To count all the close brace that
        // does not have the corresponding open brace.
        int invalidCloseBraces = 0;
  
        // Iterating over the String
        for (int i = 0; i < n; i++) {
            if (s[i] == '(') {
  
                // Number of open braces that
                // hasn't been closed yet.
                invalidOpenBraces++;
            }
            else {
                if (invalidOpenBraces == 0) {
  
                    // Number of close braces that
                    // cannot be mapped to any open brace.
                    invalidCloseBraces++;
                }
                else {
  
                    // Mapping the ith close brace to
                    // one of the open brace.
                    invalidOpenBraces--;
                }
            }
        }
        return (
            n - (invalidOpenBraces
                 + invalidCloseBraces));
    }
  
    // Driver Code
    public static void Main()
    {
        string s = "()(((((()";
        int n = s.Length;
        Console.WriteLine(maxLength(s, n));
    }
}


输出:
4

输出:

4

时间复杂度: O(n 2 )
辅助空间: O(n 2 )

方法2:此方法可以更有效地解决问题。

  1. 计算要删除的括号的长度,以获得最长的平衡括号子序列。
  2. 如果在第一个索引处,闭合括号的数量大于打开括号的数量,则必须移除该闭合括号。
  3. 计算需要移除的闭合括号的数量。
  4. 最后,多余的大括号也将被删除。
  5. 因此,要删除的总数将为多余的大括号和无效的大括号之和。

C++

// C++ program to find length of
// the longest balanced subsequence
#include 
using namespace std;
  
int maxLength(char s[], int n)
{
    // As it's subsequence - assuming first
    // open brace would map to a first close
    // brace which occurs after the open brace
    // to make subsequence balanced and second
    // open brace would map to second close
    // brace and so on.
  
    // Variable to count all the open brace
    // that does not have the corresponding
    // closing brace.
    int invalidOpenBraces = 0;
  
    // To count all the close brace that
    // does not have the corresponding open brace.
    int invalidCloseBraces = 0;
  
    // Iterating over the String
    for (int i = 0; i < n; i++) {
        if (s[i] == '(') {
  
            // Number of open braces that
            // hasn't been closed yet.
            invalidOpenBraces++;
        }
        else {
            if (invalidOpenBraces == 0) {
  
                // Number of close braces that
                // cannot be mapped to any open
                // brace.
                invalidCloseBraces++;
            }
            else {
  
                // Mapping the ith close brace
                // to one of the open brace.
                invalidOpenBraces--;
            }
        }
    }
    return (
        n - (invalidOpenBraces
             + invalidCloseBraces));
}
  
// Driver Code
int main()
{
    char s[] = "()(((((()";
    int n = strlen(s);
    cout << maxLength(s, n) << endl;
    return 0;
}

Java

// Java program to find the length of the
// longest balanced subsequence.
import java.io.*;
  
class GFG {
    static int maxLength(String s, int n)
    {
        // As it's subsequence - assuming first
        // open brace would map to a first close
        // brace which occurs after the open brace
        // to make subsequence balanced and second
        // open brace would map to second close
        // brace and so on.
  
        // Variable to count all the open brace
        // that does not have the corresponding
        // closing brace.
        int invalidOpenBraces = 0;
  
        // To count all the close brace that
        // does not have the corresponding open brace.
        int invalidCloseBraces = 0;
  
        // Iterating over the String
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '(') {
  
                // Number of open braces that
                // hasn't been closed yet.vvvvvv
                invalidOpenBraces++;
            }
            else {
                if (invalidOpenBraces == 0) {
  
                    // Number of close braces that
                    // cannot be mapped to any open
                    // brace.
                    invalidCloseBraces++;
                }
                else {
  
                    // Mapping the ith close brace
                    // to one of the open brace.
                    invalidOpenBraces--;
                }
            }
        }
        return (
            n - (invalidOpenBraces
                 + invalidCloseBraces));
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String s = "()(((((()";
        int n = s.length();
        System.out.println(maxLength(s, n));
    }
}

Python3

# Python3 program to find length of 
# the longest balanced subsequence 
  
def maxLength(s, n):
              
    # As it's subsequence - assuming first
    # open brace would map to a first close
    # brace which occurs after the open brace
    # to make subsequence balanced and second
    # open brace would map to second close 
    # brace and so on.
      
    # Variable to count all the open brace 
    # that does not have the corresponding 
    # closing brace. 
    invalidOpenBraces = 0;
  
    # To count all the close brace that does
    # not have the corresponding open brace.
    invalidCloseBraces = 0;
      
    # Iterating over the String
    for i in range(n):
        if( s[i] == '(' ):
                  
                # Number of open braces that 
                # hasn't been closed yet.
                invalidOpenBraces += 1
        else:
            if(invalidOpenBraces == 0):
                # Number of close braces that
                # cannot be mapped to any open
                # brace.
                invalidCloseBraces += 1
            else:
                # Mapping the ith close brace
                # to one of the open brace.
                invalidOpenBraces -= 1
  
    return (
n - (
invalidOpenBraces + invalidCloseBraces)) 
  
# Driver Code 
s = "()(((((()"
n = len(s)
print(maxLength(s, n))

C#

// C# program to find length of the
// longest balanced subsequence.
using System;
  
class GFG {
  
    static int maxLength(String s, int n)
    {
  
        // As it's subsequence - assuming first
        // open brace would map to a first close
        // brace which occurs after the open brace
        // to make subsequence balanced and second
        // open brace would map to second close
        // brace and so on.
  
        // Variable to count all the open brace
        // that does not have the corresponding
        // closing brace.
        int invalidOpenBraces = 0;
  
        // To count all the close brace that
        // does not have the corresponding open brace.
        int invalidCloseBraces = 0;
  
        // Iterating over the String
        for (int i = 0; i < n; i++) {
            if (s[i] == '(') {
  
                // Number of open braces that
                // hasn't been closed yet.
                invalidOpenBraces++;
            }
            else {
                if (invalidOpenBraces == 0) {
  
                    // Number of close braces that
                    // cannot be mapped to any open brace.
                    invalidCloseBraces++;
                }
                else {
  
                    // Mapping the ith close brace to
                    // one of the open brace.
                    invalidOpenBraces--;
                }
            }
        }
        return (
            n - (invalidOpenBraces
                 + invalidCloseBraces));
    }
  
    // Driver Code
    public static void Main()
    {
        string s = "()(((((()";
        int n = s.Length;
        Console.WriteLine(maxLength(s, n));
    }
}
输出:
4

时间复杂度: O(n)
辅助空间: O(1)