Given a valid expression Exp containing only binary operators ‘+‘, ‘–‘, ‘*‘, ‘/‘, and operands, remove all the redundant parenthesis. A set of parenthesis is said to be redundant if, removing them, does not change the value of the expression.
Note: The operators ‘+’ and ‘-‘ have the same priority. ‘*’ and ‘/’ also have the same priority. ‘*’ and ‘/’ have more priority than ‘+’ and ‘-‘.
Example:
Input: Exp = (A*(B+C))
Output: A*(B+C)
Explanation: The outermost parenthesis are redundant.Input: Exp = A+(B+(C))
Output: A+B+C
Explanation: All the parenthesis are redundant.
Approach: This can be solved with the following idea:
The goal is to discover which brackets from an expression can be safely eliminated by combining stack-based parsing with operator precedence rules. A further array can be used to keep track of whether each character in the input string is a redundant bracket in addition to three arrays to track the Previous and Next operators for each location.
Below are the steps involved in the implementation of the code:
- We need to first convert the input expression string “Exp” to a character array “s” and find the length of the array “n“.
- It first initializes an array ans with all 1s of length n + 1, where n is the length of the expression.
- Create two integer arrays, lasta, and nxta, with length n + 1, to store the last and next operators encountered before and after each index.
- Initialize a stack, an array sign of length 256 with -1, and an array mp of length 256 with 0. These arrays keep track of the last occurrence of an operator and whether an operator is present in the current sub-expression inside parentheses.
- Loop through the character array, updating the sign and mp arrays if the character is an operator.
- If the character is ‘(‘, push its index onto the stack. If it is ‘)’, pop the index of the corresponding opening parenthesis from the stack.
- If the character is ‘)’, check if the current set of parentheses is required by looking at the last and next operator indices of the opening and closing parentheses.
- Handle corner cases, such as the first and last characters being parentheses, and cases where no operands are present inside the parentheses.
- Update the array of ones to store whether each character is inside redundant parentheses or not.
- Construct a new string by appending all characters in the expression that are not inside redundant parentheses.
- Return the new string.
Below is the code implementation of the above approach:
// C++ code of the above approach #include <bits/stdc++.h> using namespace std;
// Function to remove redundant brackets string removeBrackets(string Exp) { char s[Exp.length() + 1];
strcpy (s, Exp.c_str());
int n = strlen (s);
int ans[n + 1];
memset (ans, 1, sizeof (ans));
int lasta[n + 1];
int nxta[n + 1];
int l = -1;
// Start Iterating from
// starting index
for ( int i = 0; i < n; i++) {
lasta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-'
|| s[i] == '/' )
l = s[i];
}
// Start Iterating from
// last index
l = -1;
for ( int i = n - 1; i >= 0; i--) {
nxta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-'
|| s[i] == '/' )
l = s[i];
}
stack< int > st;
int sign[256];
int mp[256];
memset (sign, -1, sizeof (sign));
char operand[] = { '*' , '+' , '-' , '/' };
for ( int p = 0; p < n; p++) {
for ( char x : operand) {
mp[x] = 0;
if (x == s[p])
sign[x] = p;
}
if (s[p] == '(' )
st.push(p);
else if (s[p] == ')' ) {
int i = st.top();
st.pop();
int j = p;
int nxt = nxta[j];
int last = lasta[i];
// Iterate in operator
// array
for ( char x : operand) {
if (sign[x] >= i) {
mp[x] = 1;
}
}
int ok = 0;
if (i > 0 && j + 1 < n && s[i - 1] == '('
&& s[j + 1] == ')' )
ok = 1;
if (mp[ '+' ] == 0 && mp[ '*' ] == 0 && mp[ '-' ] == 0
&& mp[ '/' ] == 0)
ok = 1;
if (last == -1 && nxt == -1)
ok = 1;
if (last == '/' ) {
}
else if (last == '-'
&& (mp[ '+' ] == 1 || mp[ '-' ] == 1)) {
}
else if (mp[ '-' ] == 0 && mp[ '+' ] == 0) {
ok = 1;
}
else {
if ((last == -1 || last == '+'
|| last == '-' )
&& (nxt == -1 || nxt == '+'
|| nxt == '-' ))
ok = 1;
}
// If the pair is redundant
if (ok == 1) {
ans[i] = 0;
ans[j] = 0;
}
}
}
// Final string
string res = "" ;
for ( int i = 0; i < n; i++) {
if (ans[i] > 0) {
res += s[i];
}
}
return res;
} // Driver code int main()
{ string expression = "(A*(B+C))" ;
// Function call
string result = removeBrackets(expression);
cout << result << endl;
return 0;
} // This code is contributed by prasad264 |
// Java code of the above approach import java.util.*;
class Solution {
// Function to redundant brackets
public static String removeBrackets(String Exp)
{
// Code here
char [] s = Exp.toCharArray();
int n = Exp.length();
int ans[] = new int [n + 1 ];
Arrays.fill(ans, 1 );
int lasta[] = new int [n + 1 ];
int nxta[] = new int [n + 1 ];
int l = - 1 ;
// Start Iterating from
// starting index
for ( int i = 0 ; i < n; i++) {
lasta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-'
|| s[i] == '/' )
l = s[i];
}
// Start Iterating from
// last index
l = - 1 ;
for ( int i = n - 1 ; i >= 0 ; i--) {
nxta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-'
|| s[i] == '/' )
l = s[i];
}
Stack<Integer> st = new Stack<>();
int sign[] = new int [ 256 ];
int mp[] = new int [ 256 ];
Arrays.fill(sign, - 1 );
char [] operand = { '*' , '+' , '-' , '/' };
for ( int p = 0 ; p < n; p++) {
for ( char x : operand) {
mp[x] = 0 ;
if (x == s[p])
sign[x] = p;
}
if (s[p] == '(' )
st.push(p);
else if (s[p] == ')' ) {
int i = st.pop();
int j = p;
int nxt = nxta[j];
int last = lasta[i];
// Iterate in operator
// array
for ( char x : operand) {
if (sign[x] >= i) {
mp[x] = 1 ;
}
}
int ok = 0 ;
if (i > 0 && j + 1 < n && s[i - 1 ] == '('
&& s[j + 1 ] == ')' )
ok = 1 ;
if (mp[ '+' ] == 0 && mp[ '*' ] == 0
&& mp[ '-' ] == 0 && mp[ '/' ] == 0 )
ok = 1 ;
if (last == - 1 && nxt == - 1 )
ok = 1 ;
if (last == '/' ) {
}
else if (last == '-'
&& (mp[ '+' ] == 1
|| mp[ '-' ] == 1 )) {
}
else if (mp[ '-' ] == 0 && mp[ '+' ] == 0 ) {
ok = 1 ;
}
else {
if ((last == - 1 || last == '+'
|| last == '-' )
&& (nxt == - 1 || nxt == '+'
|| nxt == '-' ))
ok = 1 ;
}
// If the pair is reduntant
if (ok == 1 ) {
ans[i] = 0 ;
ans[j] = 0 ;
}
}
}
// Final string
StringBuffer res = new StringBuffer();
for ( int i = 0 ; i < n; i++) {
if (ans[i] > 0 ) {
res.append(s[i]);
}
}
return res.toString();
}
// Driver code
public static void main(String[] args)
{
String expression = "(A*(B+C))" ;
// Function call
String result = removeBrackets(expression);
System.out.println(result);
}
} |
class Solution:
# Function to redundant brackets
@staticmethod
def removeBrackets(Exp):
# Code here
s = list (Exp)
n = len (Exp)
ans = [ 1 ] * (n + 1 )
lasta = [ 0 ] * (n + 1 )
nxta = [ 0 ] * (n + 1 )
l = - 1
# Start Iterating from
# starting index
for i in range (n):
lasta[i] = l
if s[i] = = '*' or s[i] = = '+' or s[i] = = '-' or s[i] = = '/' :
l = s[i]
# Start Iterating from
# last index
l = - 1
for i in range (n - 1 , - 1 , - 1 ):
nxta[i] = l
if s[i] = = '*' or s[i] = = '+' or s[i] = = '-' or s[i] = = '/' :
l = s[i]
st = []
sign = [ - 1 ] * 256
mp = [ 0 ] * 256
operand = [ '*' , '+' , '-' , '/' ]
for p in range (n):
for x in operand:
mp[ ord (x)] = 0
if x = = s[p]:
sign[ ord (x)] = p
if s[p] = = '(' :
st.append(p)
elif s[p] = = ')' :
i = st.pop()
j = p
nxt = nxta[j]
last = lasta[i]
# Iterate in operator
# array
for x in operand:
if sign[ ord (x)] > = i:
mp[ ord (x)] = 1
ok = 0
if i > 0 and j + 1 < n and s[i - 1 ] = = '(' and s[j + 1 ] = = ')' :
ok = 1
if mp[ ord ( '+' )] = = 0 and mp[ ord ( '*' )] = = 0 and mp[ ord ( '-' )] = = 0 and mp[ ord ( '/' )] = = 0 :
ok = 1
if last = = - 1 and nxt = = - 1 :
ok = 1
if last = = '/' :
pass
elif last = = '-' and (mp[ ord ( '+' )] = = 1 or mp[ ord ( '-' )] = = 1 ):
pass
elif mp[ ord ( '-' )] = = 0 and mp[ ord ( '+' )] = = 0 :
ok = 1
else :
if (last = = - 1 or last = = '+' or last = = '-' ) and (nxt = = - 1 or nxt = = '+' or nxt = = '-' ):
ok = 1
# If the pair is reduntant
if ok = = 1 :
ans[i] = 0
ans[j] = 0
# Final string
res = ""
for i in range (n):
if ans[i] > 0 :
res + = s[i]
return res
# Driver code if __name__ = = '__main__' :
expression = "(A*(B+C))"
# Function call
result = Solution.removeBrackets(expression)
print (result)
|
// C# code of the above approach using System;
using System.Collections.Generic;
using System.Text;
class Solution
{ // Function to remove redundant brackets
public static string removeBrackets( string Exp)
{
char [] s = Exp.ToCharArray();
int n = Exp.Length;
int [] ans = new int [n + 1];
Array.Fill(ans, 1);
int [] lasta = new int [n + 1];
int [] nxta = new int [n + 1];
int l = -1;
// Start Iterating from starting index
for ( int i = 0; i < n; i++)
{
lasta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-' || s[i] == '/' )
l = s[i];
}
// Start Iterating from last index
l = -1;
for ( int i = n - 1; i >= 0; i--)
{
nxta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-' || s[i] == '/' )
l = s[i];
}
Stack< int > st = new Stack< int >();
int [] sign = new int [256];
int [] mp = new int [256];
Array.Fill(sign, -1);
char [] operand = { '*' , '+' , '-' , '/' };
for ( int p = 0; p < n; p++)
{
foreach ( char x in operand)
{
mp[x] = 0;
if (x == s[p])
sign[x] = p;
}
if (s[p] == '(' )
st.Push(p);
else if (s[p] == ')' )
{
int i = st.Pop();
int j = p;
int nxt = nxta[j];
int last = lasta[i];
// Iterate in operator array
foreach ( char x in operand)
{
if (sign[x] >= i)
mp[x] = 1;
}
int ok = 0;
if (i > 0 && j + 1 < n && s[i - 1] == '(' && s[j + 1] == ')' )
ok = 1;
if (mp[ '+' ] == 0 && mp[ '*' ] == 0 && mp[ '-' ] == 0 && mp[ '/' ] == 0)
ok = 1;
if (last == -1 && nxt == -1)
ok = 1;
if (last == '/' )
{
}
else if (last == '-' && (mp[ '+' ] == 1 || mp[ '-' ] == 1))
{
}
else if (mp[ '-' ] == 0 && mp[ '+' ] == 0)
{
ok = 1;
}
else
{
if ((last == -1 || last == '+' || last == '-' ) && (nxt == -1 || nxt == '+' || nxt == '-' ))
ok = 1;
}
// If the pair is redundant
if (ok == 1)
{
ans[i] = 0;
ans[j] = 0;
}
}
}
// Final string
StringBuilder res = new StringBuilder();
for ( int i = 0; i < n; i++)
{
if (ans[i] > 0)
res.Append(s[i]);
}
return res.ToString();
}
// Driver code
public static void Main( string [] args)
{
string expression = "(A*(B+C))" ;
// Function call
string result = removeBrackets(expression);
Console.WriteLine(result);
}
} // This code is contributed by Utkarsh Kumar |
function removeBrackets(exp) {
let s = exp.split( '' );
let n = s.length;
let ans = new Array(n + 1).fill(1);
let lasta = new Array(n + 1);
let nxta = new Array(n + 1);
let l = -1;
// Start Iterating from
// starting index
for (let i = 0; i < n; i++) {
lasta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-' || s[i] == '/' )
l = s[i];
}
// Start Iterating from
// last index
l = -1;
for (let i = n - 1; i >= 0; i--) {
nxta[i] = l;
if (s[i] == '*' || s[i] == '+' || s[i] == '-' || s[i] == '/' )
l = s[i];
}
let st = [];
let sign = new Array(256).fill(-1);
let mp = new Array(256).fill(0);
let operand = [ '*' , '+' , '-' , '/' ];
for (let p = 0; p < n; p++) {
for (let x of operand) {
mp[x] = 0;
if (x == s[p])
sign[x] = p;
}
if (s[p] == '(' )
st.push(p);
else if (s[p] == ')' ) {
let i = st.pop();
let j = p;
let nxt = nxta[j];
let last = lasta[i];
// Iterate in operator
// array
for (let x of operand) {
if (sign[x] >= i) {
mp[x] = 1;
}
}
let ok = 0;
if (i > 0 && j + 1 < n && s[i - 1] == '(' && s[j + 1] == ')' )
ok = 1;
if (mp[ '+' ] == 0 && mp[ '*' ] == 0 && mp[ '-' ] == 0 && mp[ '/' ] == 0)
ok = 1;
if (last == -1 && nxt == -1)
ok = 1;
if (last == '/' ) {
}
else if (last == '-' && (mp[ '+' ] == 1 || mp[ '-' ] == 1)) {
}
else if (mp[ '-' ] == 0 && mp[ '+' ] == 0) {
ok = 1;
}
else {
if ((last == -1 || last == '+' || last == '-' ) && (nxt == -1 || nxt == '+' || nxt == '-' ))
ok = 1;
}
// If the pair is redundant
if (ok == 1) {
ans[i] = 0;
ans[j] = 0;
}
}
}
// Final string
let res = "" ;
for (let i = 0; i < n; i++) {
if (ans[i] > 0) {
res += s[i];
}
}
return res;
} // Driver code let expression = "(A*(B+C))" ;
// Function call let result = removeBrackets(expression); console.log(result); //This code is contributed by Tushar Rokade |
A*(B+C)
Time Complexity: O(N)
Auxiliary Space: O(N)