📜  使表达式平衡所需的最小括号反转次数

📅  最后修改于: 2022-05-13 01:57:00.716000             🧑  作者: Mango

使表达式平衡所需的最小括号反转次数

给定一个只有 '}' 和 '{' 的表达式。表达可能不平衡。找出使表达式平衡的最小括号反转次数。
例子:

Input:  exp = "}{"
Output: 2
We need to change '}' to '{' and '{' to
'}' so that the expression becomes balanced, 
the balanced expression is '{}'

Input:  exp = "{{{"
Output: Can't be made balanced using reversals

Input:  exp = "{{{{"
Output: 2 

Input:  exp = "{{{{}}"
Output: 1 

Input:  exp = "}{{}}{{{"
Output: 3

一个简单的观察是,只有当括号总数为偶数时才能平衡字符串('{'和'}'必须相等)
一个朴素的解决方案是考虑每个括号,并通过采取两种情况(i)保持括号原样(ii)反转括号来递归计算反转次数。如果我们得到一个平衡的表达式,如果到达这里所遵循的步骤数小于到目前为止的最小值,我们就会更新结果。此解决方案的时间复杂度为 O(2 n )。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。

一个有效的解决方案可以在 O(n) 时间内解决这个问题。这个想法是首先删除表达式的所有平衡部分。例如,通过删除突出显示的部分将“} {{}} {{{”转换为“}{{{”。如果我们仔细观察,我们会注意到,在去除平衡部分后,我们总是以形式为 }}…}{{…{ 的表达式结束,该表达式包含 0 个或多个右括号后跟 0或更多数量的左括号。
形式为“}}..}{{..{”的表达式需要多少次最小反转?让 m 是右括号的总数,n 是左括号的数量。我们需要 ⌈m/2⌉ + ⌈n/2⌉ 反转。例如 }}}}{{ 需要 2+1 次反转。
以下是上述想法的实现:



C++14
// C++ program to find minimum number of
// reversals required to balance an expression
#include
using namespace std;
 
 
// Returns count of minimum reversals for making
// expr balanced. Returns -1 if expr cannot be
// balanced.
int countMinReversals(string expr)
{
    int len = expr.length();
 
    // length of expression must be even to make
    // it balanced by using reversals.
    if (len%2)
       return -1;
 
    // After this loop, stack contains unbalanced
    // part of expression, i.e., expression of the
    // form "}}..}{{..{"
    stack s;
    for (int i=0; i


Java
//Java Code to count minimum reversal for
//making an expression balanced.
 
import java.util.Stack;
 
public class GFG
{
 
    // Method count minimum reversal for
    //making an expression balanced.
    //Returns -1 if expression cannot be balanced
    static int countMinReversals(String expr)
    {
        int len = expr.length();
     
        // length of expression must be even to make
        // it balanced by using reversals.
        if (len%2 != 0)
        return -1;
     
        // After this loop, stack contains unbalanced
        // part of expression, i.e., expression of the
        // form "}}..}{{..{"
        Stack s=new Stack<>();
         
        for (int i=0; i


Python3
# Python3 program to find minimum number of
# reversals required to balance an expression
 
# Returns count of minimum reversals
# for making expr balanced. Returns -1
# if expr cannot be balanced.
def countMinReversals(expr):
 
    lenn = len(expr)
 
    # length of expression must be even
    # to make it balanced by using reversals.
    if (lenn % 2) :
        return -1
 
    # After this loop, stack contains
    # unbalanced part of expression, 
    # i.e., expression of the form "...."
    s = []
    for i in range(lenn):
        if (expr[i] =='' and len(s)):
 
            if (s[0] == '') :
                s.pop(0)
            else:
                s.insert(0, expr[i])
        else:
            s.insert(0, expr[i])
     
    # Length of the reduced expression
    # red_len = (m+n)
    red_len = len(s)
 
    # count opening brackets at the
    # end of stack
    n = 0
    while (len(s)and s[0] == '') :
            s.pop(0)
            n += 1
 
    # return ceil(m/2) + ceil(n/2) which
    # is actually equal to (m+n)/2 + n%2
    # when m+n is even.
    return (red_len // 2 + n % 2)
 
# Driver Code
if __name__ == '__main__':
 
    expr = "}}{{"
    print(countMinReversals(expr.strip()))
 
# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)


C#
// C# Code to count minimum reversal for
// making an expression balanced.
using System;
using System.Collections.Generic;
 
class GFG
{
 
// Method count minimum reversal for
// making an expression balanced.
// Returns -1 if expression cannot be balanced
public static int countMinReversals(string expr)
{
    int len = expr.Length;
 
    // length of expression must be
    // even to make it balanced by
    // using reversals.
    if (len % 2 != 0)
    {
        return -1;
    }
 
    // After this loop, stack contains
    // unbalanced part of expression,
    // i.e., expression of the form "}}..}{{..{"
    Stack s = new Stack();
 
    for (int i = 0; i < len; i++)
    {
        char c = expr[i];
        if (c == '}' && s.Count > 0)
        {
            if (s.Peek() == '{')
            {
                s.Pop();
            }
            else
            {
                s.Push(c);
            }
        }
        else
        {
            s.Push(c);
        }
    }
 
    // Length of the reduced expression
    // red_len = (m+n)
    int red_len = s.Count;
 
    // count opening brackets at
    // the end of stack
    int n = 0;
    while (s.Count > 0 && s.Peek() == '{')
    {
        s.Pop();
        n++;
    }
 
    // return ceil(m/2) + ceil(n/2) which is
    // actually equal to (m+n)/2 + n%2 when
    // m+n is even.
    return (red_len / 2 + n % 2);
}
 
// Driver Code
public static void Main(string[] args)
{
    string expr = "}}{{";
 
    Console.WriteLine(countMinReversals(expr));
}
}
 
// This code is contributed by Shrikant13


Javascript


C++
// C++ program to find minimum number of
// reversals required to balance an expression
#include 
using namespace std;
 
// Returns count of minimum reversals for making
// expr balanced. Returns -1 if expr cannot be
// balanced.
int countMinReversals(string expr)
{
    int len = expr.length();
   
    // Expressions of odd lengths
    // cannot be balanced
    if (len % 2 != 0) {
        return -1;
    }
    int left_brace = 0, right_brace = 0;
    int ans;
    for (int i = 0; i < len; i++) {
       
        // If we find a left bracket then we simply
        // increment the left bracket
        if (expr[i] == '{') {
            left_brace++;
        }
       
        // Else if left bracket is 0 then we find
        // unbalanced right bracket and increment
        // right bracket or if the expression
        // is balanced then we decrement left
        else {
            if (left_brace == 0) {
                right_brace++;
            }
            else {
                left_brace--;
            }
        }
    }
    ans = ceil(left_brace / 2.0) + ceil(right_brace / 2.0);
    return ans;
}
 
// Driver program to test above function
int main()
{
    string expr = "}}{{";
    cout << countMinReversals(expr);
    return 0;
}


Java
// Java Code to count minimum reversal for
// making an expression balanced.
import java.util.*;
public class GFG {
 
    // Method count minimum reversal for
    // making an expression balanced.
    // Returns -1 if expression cannot be balanced
    static int countMinReversals(String expr)
    {
        int len = expr.length();
        int ans;
       
        // Expressions of odd lengths
        // cannot be balanced
        if (len % 2 != 0) {
            return -1;
        }
        int left_brace = 0, right_brace = 0;
        for (int i = 0; i < len; i++) {
            char ch = expr.charAt(i);
           
            // If we find a left bracket then we simply
            // increment the left bracket
            if (ch == '{') {
                left_brace++;
            }
           
            // Else if left bracket is 0 then we find
            // unbalanced right bracket and increment
            // right bracket or if the expression
            // is balanced then we decrement left
            else {
                if (left_brace == 0) {
                    right_brace++;
                }
                else {
                    left_brace--;
                }
            }
        }
        ans = (int)(Math.ceil((0.0 + left_brace) / 2)
                    + Math.ceil((0.0 + right_brace) / 2));
        return ans;
    }
 
    // Driver method
    public static void main(String[] args)
    {
        String expr = "}}{{";
 
        System.out.println(countMinReversals(expr));
    }
}


Python3
# Python 3 program to find minimum number of
# reversals required to balance an expression
import math
 
# Returns count of minimum reversals for making
# expr balanced. Returns -1 if expr cannot be
# balanced.
def countMinReversals(expr):
    length = len(expr)
 
    # Expressions of odd lengths
    # cannot be balanced
    if (length % 2 != 0):
        return -1
 
    left_brace = 0
    right_brace = 0
 
    for i in range(length):
 
        # If we find a left bracket then we simply
        # increment the left bracket
        if (expr[i] == '{'):
            left_brace += 1
 
        # Else if left bracket is 0 then we find
        # unbalanced right bracket and increment
        # right bracket or if the expression
        # is balanced then we decrement left
        else:
            if (left_brace == 0):
                right_brace += 1
 
            else:
                left_brace -= 1
 
    ans = math.ceil(left_brace / 2) + math.ceil(right_brace / 2)
    return ans
 
# Driver program to test above function
if __name__ == "__main__":
 
    expr = "}}{{"
    print(countMinReversals(expr))
 
    # This code is contributed by ukasp.


C#
// C# Code to count minimum reversal for
// making an expression balanced.
using System;
 
public class GFG {
 
    // Method count minimum reversal for
    // making an expression balanced.
    // Returns -1 if expression cannot be balanced
    static int countMinReversals(String expr)
    {
        int len = expr.Length;
        int ans;
       
        // Expressions of odd lengths
        // cannot be balanced
        if (len % 2 != 0) {
            return -1;
        }
        int left_brace = 0, right_brace = 0;
        for (int i = 0; i < len; i++) {
            char ch = expr[i];
           
            // If we find a left bracket then we simply
            // increment the left bracket
            if (ch == '{') {
                left_brace++;
            }
           
            // Else if left bracket is 0 then we find
            // unbalanced right bracket and increment
            // right bracket or if the expression
            // is balanced then we decrement left
            else {
                if (left_brace == 0) {
                    right_brace++;
                }
                else {
                    left_brace--;
                }
            }
        }
        ans = (int)(Math.Ceiling((0.0 + left_brace) / 2)
                    + Math.Ceiling((0.0 + right_brace) / 2));
        return ans;
    }
 
    // Driver method
    public static void Main(String[] args)
    {
        String expr = "}}{{";
 
        Console.WriteLine(countMinReversals(expr));
    }
}
 
// This code is contributed by aashish1995.


Javascript


C++
// C++ program to find minimum number of
// reversals required to balance an expression
#include 
using namespace std;
 
// Returns count of minimum reversals for making
// expr balanced. Returns -1 if expr cannot be
// balanced.
int countMinReversals(string s)
{
   int temp=0, res=0, n=s.size();
   if(n%2!=0)
           return -1;
   for(int i=0;i0)
       res += temp/2;
   return res;
}
 
// Driver program to test above function
int main()
{
string expr = "}}{{";
cout << countMinReversals(expr);
return 0;
//This code is contributed by Akansha Mittal
}


输出
2

输出:

2

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

另一个有效的解决方案在 O(1) 中解决问题,即常数空间。由于表达式只包含一种类型的括号,想法是维护两个变量来保持左括号和右括号的计数,就像我们在最长有效子字符串的长度中所做的那样。如果表达式有平衡括号,那么我们递减左变量,否则递增右变量。那么我们需要返回的只是 ceil(left/2) + ceil(right/2)。

C++

// C++ program to find minimum number of
// reversals required to balance an expression
#include 
using namespace std;
 
// Returns count of minimum reversals for making
// expr balanced. Returns -1 if expr cannot be
// balanced.
int countMinReversals(string expr)
{
    int len = expr.length();
   
    // Expressions of odd lengths
    // cannot be balanced
    if (len % 2 != 0) {
        return -1;
    }
    int left_brace = 0, right_brace = 0;
    int ans;
    for (int i = 0; i < len; i++) {
       
        // If we find a left bracket then we simply
        // increment the left bracket
        if (expr[i] == '{') {
            left_brace++;
        }
       
        // Else if left bracket is 0 then we find
        // unbalanced right bracket and increment
        // right bracket or if the expression
        // is balanced then we decrement left
        else {
            if (left_brace == 0) {
                right_brace++;
            }
            else {
                left_brace--;
            }
        }
    }
    ans = ceil(left_brace / 2.0) + ceil(right_brace / 2.0);
    return ans;
}
 
// Driver program to test above function
int main()
{
    string expr = "}}{{";
    cout << countMinReversals(expr);
    return 0;
}

Java

// Java Code to count minimum reversal for
// making an expression balanced.
import java.util.*;
public class GFG {
 
    // Method count minimum reversal for
    // making an expression balanced.
    // Returns -1 if expression cannot be balanced
    static int countMinReversals(String expr)
    {
        int len = expr.length();
        int ans;
       
        // Expressions of odd lengths
        // cannot be balanced
        if (len % 2 != 0) {
            return -1;
        }
        int left_brace = 0, right_brace = 0;
        for (int i = 0; i < len; i++) {
            char ch = expr.charAt(i);
           
            // If we find a left bracket then we simply
            // increment the left bracket
            if (ch == '{') {
                left_brace++;
            }
           
            // Else if left bracket is 0 then we find
            // unbalanced right bracket and increment
            // right bracket or if the expression
            // is balanced then we decrement left
            else {
                if (left_brace == 0) {
                    right_brace++;
                }
                else {
                    left_brace--;
                }
            }
        }
        ans = (int)(Math.ceil((0.0 + left_brace) / 2)
                    + Math.ceil((0.0 + right_brace) / 2));
        return ans;
    }
 
    // Driver method
    public static void main(String[] args)
    {
        String expr = "}}{{";
 
        System.out.println(countMinReversals(expr));
    }
}

蟒蛇3

# Python 3 program to find minimum number of
# reversals required to balance an expression
import math
 
# Returns count of minimum reversals for making
# expr balanced. Returns -1 if expr cannot be
# balanced.
def countMinReversals(expr):
    length = len(expr)
 
    # Expressions of odd lengths
    # cannot be balanced
    if (length % 2 != 0):
        return -1
 
    left_brace = 0
    right_brace = 0
 
    for i in range(length):
 
        # If we find a left bracket then we simply
        # increment the left bracket
        if (expr[i] == '{'):
            left_brace += 1
 
        # Else if left bracket is 0 then we find
        # unbalanced right bracket and increment
        # right bracket or if the expression
        # is balanced then we decrement left
        else:
            if (left_brace == 0):
                right_brace += 1
 
            else:
                left_brace -= 1
 
    ans = math.ceil(left_brace / 2) + math.ceil(right_brace / 2)
    return ans
 
# Driver program to test above function
if __name__ == "__main__":
 
    expr = "}}{{"
    print(countMinReversals(expr))
 
    # This code is contributed by ukasp.

C#

// C# Code to count minimum reversal for
// making an expression balanced.
using System;
 
public class GFG {
 
    // Method count minimum reversal for
    // making an expression balanced.
    // Returns -1 if expression cannot be balanced
    static int countMinReversals(String expr)
    {
        int len = expr.Length;
        int ans;
       
        // Expressions of odd lengths
        // cannot be balanced
        if (len % 2 != 0) {
            return -1;
        }
        int left_brace = 0, right_brace = 0;
        for (int i = 0; i < len; i++) {
            char ch = expr[i];
           
            // If we find a left bracket then we simply
            // increment the left bracket
            if (ch == '{') {
                left_brace++;
            }
           
            // Else if left bracket is 0 then we find
            // unbalanced right bracket and increment
            // right bracket or if the expression
            // is balanced then we decrement left
            else {
                if (left_brace == 0) {
                    right_brace++;
                }
                else {
                    left_brace--;
                }
            }
        }
        ans = (int)(Math.Ceiling((0.0 + left_brace) / 2)
                    + Math.Ceiling((0.0 + right_brace) / 2));
        return ans;
    }
 
    // Driver method
    public static void Main(String[] args)
    {
        String expr = "}}{{";
 
        Console.WriteLine(countMinReversals(expr));
    }
}
 
// This code is contributed by aashish1995.

Javascript


输出
2

时间复杂度:O(n)

辅助空间:O(1)

我们可以使用单个临时变量来完成,而不是为左大括号和右大括号维护两个不同的变量。



遍历数组。对于每个 '{' ,将 temp 的值增加 1,对于每个 '}',如果 temp 的值 >0,则将 temp 的值减少 1 否则,将 result 和 temp 的值增加 1。最后,将 temp 值的一半添加到结果中。

下面是上述方法在 C++ 中的实现。

C++

// C++ program to find minimum number of
// reversals required to balance an expression
#include 
using namespace std;
 
// Returns count of minimum reversals for making
// expr balanced. Returns -1 if expr cannot be
// balanced.
int countMinReversals(string s)
{
   int temp=0, res=0, n=s.size();
   if(n%2!=0)
           return -1;
   for(int i=0;i0)
       res += temp/2;
   return res;
}
 
// Driver program to test above function
int main()
{
string expr = "}}{{";
cout << countMinReversals(expr);
return 0;
//This code is contributed by Akansha Mittal
}
输出
2

时间复杂度: O(n)

辅助空间: O(1)