📌  相关文章
📜  重新安排子字符串以将字符串转换为平衡括号序列的成本降至最低

📅  最后修改于: 2021-05-17 05:00:54             🧑  作者: Mango

给定长度为N的字符串S (仅由字符“(”“)”组成) ,任务是通过从给定字符串S中选择任何子字符串,并将给定字符串的字符重新排序,将给定字符串转换为平衡的括号序列。将每个子串的长度视为每次操作的成本,请最小化所需的总成本。

例子:

方法:想法是首先检查字符串可以平衡,即计算开括号和闭括号的数目,如果不相等,则打印-1 。否则,请按照以下步骤查找最低总费用:

  • 初始化长度为N的数组arr []
  • 初始化作为0来更新与所述值总和的数组元素。
  • i = 0N – 1遍历给定的字符串,然后执行以下步骤:
    • 如果当前字符为“(” ,则将arr [i]更新为(sum + 1) 。否则,将arr [i]更新为(sum – 1)
    • sum的值更新为arr [i]
  • 完成上述步骤后,如果arr [N – 1]的值不为零,则无法平衡字符串并显示“ -1”
  • 如果字符串可以平衡,则打印结果为sum 0的不相交子数组的大小之和。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to count minimum number of
// operations to convert the string to
// a balanced bracket sequence
void countMinMoves(string str)
{
    int n = str.size();
 
    // Initialize the integer array
    int a[n] = { 0 };
    int j, ans = 0, i, sum = 0;
 
    // Traverse the string
    for (i = 0; i < n; i++) {
 
        // Decrement a[i]
        if (str[i] == ')') {
            a[i] += sum - 1;
        }
 
        // Increment a[i]
        else {
            a[i] += sum + 1;
        }
 
        // Update the sum as current
        // value of arr[i]
        sum = a[i];
    }
 
    // If answer exists
    if (sum == 0) {
 
        // Traverse from i
        i = 1;
 
        // Find all substrings with 0 sum
        while (i < n) {
            j = i - 1;
 
            while (i < n && a[i] != 0)
                i++;
 
            if (i < n && a[i - 1] < 0) {
                ans += i - j;
                if (j == 0)
                    ans++;
            }
            i++;
        }
 
        // Print the sum of sizes
        cout << ans << endl;
    }
 
    // No answer exists
    else
        cout << "-1\n";
}
 
// Driver Code
int main()
{
    string str = ")(()";
    countMinMoves(str);
 
    return 0;
}


Java
// Java program for the above approach
class GFG
{
 
  // Function to count minimum number of
  // operations to convert the string to
  // a balanced bracket sequence
  static void countMinMoves(String str)
  {
    int n = str.length();
 
    // Initialize the integer array
    int a[] = new int[n];
    int j, ans = 0, i, sum = 0;
 
    // Traverse the string
    for (i = 0; i < n; i++)
    {
 
      // Decrement a[i]
      if (str.charAt(i) == ')')
      {
        a[i] += sum - 1;
      }
 
      // Increment a[i]
      else
      {
        a[i] += sum + 1;
      }
 
      // Update the sum as current
      // value of arr[i]
      sum = a[i];
    }
 
    // If answer exists
    if (sum == 0)
    {
 
      // Traverse from i
      i = 1;
 
      // Find all substrings with 0 sum
      while (i < n)
      {
        j = i - 1;
 
        while (i < n && a[i] != 0)
          i++;
 
        if (i < n && a[i - 1] < 0)
        {
          ans += i - j;
          if (j == 0)
            ans++;
        }
        i++;
      }
 
      // Print the sum of sizes
      System.out.println(ans);
    }
 
    // No answer exists
    else
      System.out.println("-1");
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    String str = ")(()";
    countMinMoves(str);
  }
}
 
// This code is contributed by AnkThon


Python3
# Python3 program for the above approach
 
# Function to count minimum number of
# operations to convert the string to
# a balanced bracket sequence
def countMinMoves(str):
     
    n = len(str)
     
    # Initialize the integer array
    a = [0 for i in range(n)]
    j, ans, sum = 0, 0, 0
 
    # Traverse the string
    for i in range(n):
         
        # Decrement a[i]
        if (str[i] == ')'):
            a[i] += sum - 1
             
        # Increment a[i]
        else:
            a[i] += sum + 1
 
        # Update the sum as current
        # value of arr[i]
        sum = a[i]
 
    # If answer exists
    if (sum == 0):
         
        # Traverse from i
        i = 1
         
        # Find all substrings with 0 sum
        while (i < n):
            j = i - 1
 
            while (i < n and a[i] != 0):
                i += 1
 
            if (i < n and a[i - 1] < 0):
                ans += i - j
                 
                if (j == 0):
                    ans += 1
                     
            i += 1
 
        # Print the sum of sizes
        print(ans)
 
    # No answer exists
    else:
        print("-1")
 
# Driver Code
if __name__ == '__main__':
     
    str = ")(()"
     
    countMinMoves(str)
 
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
class GFG
{
 
  // Function to count minimum number of
  // operations to convert the string to
  // a balanced bracket sequence
  static void countMinMoves(string str)
  {
    int n = str.Length;
 
    // Initialize the integer array
    int []a = new int[n];
    int j, ans = 0, i, sum = 0;
 
    // Traverse the string
    for (i = 0; i < n; i++)
    {
 
      // Decrement a[i]
      if (str[i] == ')')
      {
        a[i] += sum - 1;
      }
 
      // Increment a[i]
      else
      {
        a[i] += sum + 1;
      }
 
      // Update the sum as current
      // value of arr[i]
      sum = a[i];
    }
 
    // If answer exists
    if (sum == 0)
    {
 
      // Traverse from i
      i = 1;
 
      // Find all substrings with 0 sum
      while (i < n)
      {
        j = i - 1;
 
        while (i < n && a[i] != 0)
          i++;
 
        if (i < n && a[i - 1] < 0)
        {
          ans += i - j;
          if (j == 0)
            ans++;
        }
        i++;
      }
 
      // Print the sum of sizes
      Console.WriteLine(ans);
    }
 
    // No answer exists
    else
      Console.WriteLine("-1");
  }
 
  // Driver Code
  public static void Main()
  {
    string str = ")(()";
    countMinMoves(str);
  }
}
 
// This code is contributed by bgangwar59


输出:
2

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