使表达式平衡所需的最小括号反转次数
给定一个只有 '}' 和 '{' 的表达式。表达可能不平衡。找出使表达式平衡的最小括号反转次数。
例子:
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)