Remove Invalid Parentheses
An expression will be given which can contain open and close parentheses and optionally some characters, No other operator will be there in string. We need to remove minimum number of parentheses to make the input string valid. If more than one valid output are possible removing same number of parentheses then print all such output.
Examples:
Input : str = “()())()” -
Output : ()()() (())()
There are two possible solutions
"()()()" and "(())()"
Input : str = (v)())()
Output : (v)()() (v())()
As we need to generate all possible output we will backtrack among all states by removing one opening or closing bracket and check if they are valid if invalid then add the removed bracket back and go for next state. We will use BFS for moving through states, use of BFS will assure removal of minimal number of brackets because we traverse into states level by level and each level corresponds to one extra bracket removal. Other than this BFS involve no recursion so overhead of passing parameters is also saved.
Below code has a method isValidString to check validity of string, it counts open and closed parenthesis at each index ignoring non-parenthesis character. If at any instant count of close parenthesis becomes more than open then we return false else we keep update the count variable.
C++
#include <bits/stdc++.h>
using namespace std;
bool isParenthesis( char c)
{
return ((c == '(' ) || (c == ')' ));
}
bool isValidString(string str)
{
int cnt = 0;
for ( int i = 0; i < str.length(); i++)
{
if (str[i] == '(' )
cnt++;
else if (str[i] == ')' )
cnt--;
if (cnt < 0)
return false ;
}
return (cnt == 0);
}
void removeInvalidParenthesis(string str)
{
if (str.empty())
return ;
unordered_set<string> visit;
queue<string> q;
string temp;
bool level;
q.push(str);
visit.insert(str);
while (!q.empty())
{
str = q.front(); q.pop();
if (isValidString(str))
{
cout << str << endl;
level = true ;
}
if (level)
continue ;
for ( int i = 0; i < str.length(); i++)
{
if (!isParenthesis(str[i]))
continue ;
temp = str.substr(0, i) + str.substr(i + 1);
if (visit.find(temp) == visit.end())
{
q.push(temp);
visit.insert(temp);
}
}
}
}
int main()
{
string expression = "()())()" ;
removeInvalidParenthesis(expression);
expression = "()v)" ;
removeInvalidParenthesis(expression);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static boolean isParenthesis( char c)
{
return ((c == '(' ) || (c == ')' ));
}
static boolean isValidString(String str)
{
int cnt = 0 ;
for ( int i = 0 ; i < str.length(); i++)
{
if (str.charAt(i) == '(' )
cnt++;
else if (str.charAt(i) == ')' )
cnt--;
if (cnt < 0 )
return false ;
}
return (cnt == 0 );
}
static void removeInvalidParenthesis(String str)
{
if (str.isEmpty())
return ;
HashSet<String> visit = new HashSet<String>();
Queue<String> q = new LinkedList<>();
String temp;
boolean level = false ;
q.add(str);
visit.add(str);
while (!q.isEmpty())
{
str = q.peek(); q.remove();
if (isValidString(str))
{
System.out.println(str);
level = true ;
}
if (level)
continue ;
for ( int i = 0 ; i < str.length(); i++)
{
if (!isParenthesis(str.charAt(i)))
continue ;
temp = str.substring( 0 , i) + str.substring(i + 1 );
if (!visit.contains(temp))
{
q.add(temp);
visit.add(temp);
}
}
}
}
public static void main(String[] args)
{
String expression = "()())()" ;
removeInvalidParenthesis(expression);
expression = "()v)" ;
removeInvalidParenthesis(expression);
}
}
|
Python3
def isParenthesis(c):
return ((c = = '(' ) or (c = = ')' ))
def isValidString( str ):
cnt = 0
for i in range ( len ( str )):
if ( str [i] = = '(' ):
cnt + = 1
elif ( str [i] = = ')' ):
cnt - = 1
if (cnt < 0 ):
return False
return (cnt = = 0 )
def removeInvalidParenthesis( str ):
if ( len ( str ) = = 0 ):
return
visit = set ()
q = []
temp = 0
level = 0
q.append( str )
visit.add( str )
while ( len (q)):
str = q[ 0 ]
q.pop( 0 )
if (isValidString( str )):
print ( str )
level = True
if (level):
continue
for i in range ( len ( str )):
if ( not isParenthesis( str [i])):
continue
temp = str [ 0 :i] + str [i + 1 :]
if temp not in visit:
q.append(temp)
visit.add(temp)
expression = "()())()"
removeInvalidParenthesis(expression)
expression = "()v)"
removeInvalidParenthesis(expression)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool isParenthesis( char c)
{
return ((c == '(' ) || (c == ')' ));
}
static bool isValidString(String str)
{
int cnt = 0;
for ( int i = 0; i < str.Length; i++)
{
if (str[i] == '(' )
cnt++;
else if (str[i] == ')' )
cnt--;
if (cnt < 0)
return false ;
}
return (cnt == 0);
}
static void removeInvalidParenthesis(String str)
{
if (str == null || str == "" )
return ;
HashSet<String> visit = new HashSet<String>();
Queue<String> q = new Queue<String>();
String temp;
bool level = false ;
q.Enqueue(str);
visit.Add(str);
while (q.Count != 0)
{
str = q.Peek(); q.Dequeue();
if (isValidString(str))
{
Console.WriteLine(str);
level = true ;
}
if (level)
continue ;
for ( int i = 0; i < str.Length; i++)
{
if (!isParenthesis(str[i]))
continue ;
temp = str.Substring(0, i) +
str.Substring(i + 1);
if (!visit.Contains(temp))
{
q.Enqueue(temp);
visit.Add(temp);
}
}
}
}
public static void Main(String[] args)
{
String expression = "()())()" ;
removeInvalidParenthesis(expression);
expression = "()v)" ;
removeInvalidParenthesis(expression);
}
}
|
Javascript
<script>
function isParenthesis(c)
{
return ((c == '(' ) || (c == ')' ));
}
function isValidString(str)
{
let cnt = 0;
for (let i = 0; i < str.length; i++)
{
if (str[i] == '(' )
cnt++;
else if (str[i] == ')' )
cnt--;
if (cnt < 0)
return false ;
}
return (cnt == 0);
}
function removeInvalidParenthesis(str)
{
if (str.length==0)
return ;
let visit = new Set();
let q = [];
let temp;
let level = false ;
q.push(str);
visit.add(str);
while (q.length!=0)
{
str = q.shift();
if (isValidString(str))
{
document.write(str+ "<br>" );
level = true ;
}
if (level)
continue ;
for (let i = 0; i < str.length; i++)
{
if (!isParenthesis(str[i]))
continue ;
temp = str.substring(0, i) + str.substring(i + 1);
if (!visit.has(temp))
{
q.push(temp);
visit.add(temp);
}
}
}
}
let expression = "()())()" ;
removeInvalidParenthesis(expression);
expression = "()v)" ;
removeInvalidParenthesis(expression);
</script>
|
Output:
(())()
()()()
(v)
()v
The time and space complexity of the given program are as follows:
Time complexity:
The program uses a BFS (breadth-first search) approach to traverse all possible combinations of removing invalid parentheses from the input string. The worst-case time complexity of BFS is exponential, O(b^d), where b is the branching factor (the average number of child nodes per node) and d is the depth of the search tree. In the given program, the branching factor is at most 2 (either remove or keep a parenthesis at each position), and the depth can be up to the length of the input string. Therefore, the worst-case time complexity of the program is O(2^n), where n is the length of the input string.
Space complexity:
The program uses a queue to store the intermediate strings during the BFS traversal. The maximum size of the queue can be at most O(2^n), as there can be up to 2^n valid combinations of parentheses. Additionally, the program uses an unordered set to keep track of the visited strings and avoid duplicates. The size of the set can also be up to O(2^n), as each valid combination can potentially be a unique string. Therefore, the space complexity of the program is O(2^n).
Last Updated :
18 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...