Remove Invalid Parentheses
Last Updated :
08 May, 2025
Given a string str consisting only of lowercase letters and the characters '(' and ')'. Your task is to delete minimum parentheses so that the resulting string is balanced, i.e., every opening parenthesis has a matching closing parenthesis in the correct order, and no extra closing parentheses appear. Print all distinct strings you can obtain by performing the minimum number of removals.
Examples:
Input: str = "()())()"
Output: "()()()" "(())()"
Explanation: We can remove the closing bracket at index 3 to obtain the balanced string "()()()". Similarly, we can remove the closing bracket at index 1 to obtain the balanced string "(())()".
Input: str = "(v)())()"
Output: "(v)()()" "(v())()"
Explanation: The given string is the modified version of first string containing a letter 'v' . As the letters do not differ the parentheses, the solution remains the same.
Input: S = ")("
Output: ""
Using Breadth First Search - O(2 ^ n) Time and O(2 ^ n) Space
The idea is to remove brackets one by one and check for balance. To remove brackets in a systematic way, we use BFS order. We remove one bracket at a time, check for balance, then remove more brackets and again check in BFS manner. We stop when we find a balanced string.
One important observation about this problem is, we can check the balancing by simply counting opening and closing brackets because we have only one type of brackets. We do not need to use stack to check.
Follow the below given steps:
- Initialize an empty
visit
map, a queue q
, a result vector res
, and a boolean level = false
. - Push the original
str
into q
and mark visit[str] = 1
. - While
q
is not empty:- Dequeue
temp
from q
. - If
isValidString(temp)
returns true:- Append
temp
to res
. - Set
level = true
.
- If
level
is true, skip further removals at this depth and continue. - Otherwise, for each index
i
in temp
where temp[i]
is ‘(’ or ‘)’:- Form
cur = temp.substr(0, i) + temp.substr(i + 1)
. - If
visit.count(cur) == 0
, enqueue cur
into q
and set visit[cur] = 1
.
- Return
res
.
Below is given the implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// method returns true if string
// contains valid parenthesis
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);
}
// function to remove invalid parenthesis
vector<string> validParenthesis(string &str) {
// to ignore already visited string
unordered_map<string, int> visit;
// queue to maintain BFS
queue<string> q;
// to store the valid strings
vector<string> res;
bool level = false;
// pushing given string as starting node into queue
q.push(str);
// mark the string as visited
visit[str] = 1;
// while queue is not empty
while (!q.empty()) {
string temp = q.front();
q.pop();
// check if the string is valid
if (isValidString(temp)) {
// if valid, store it
res.push_back(temp);
// make level true, so that valid string
// of only that level are processed.
level = true;
}
if (level)
continue;
for (int i = 0; i < temp.length(); i++) {
// if current character is not a parenthesis
// continue to next character
if (temp[i] != '(' && temp[i] != ')')
continue;
// Removing parenthesis from str and
// pushing into queue,if not visited already
string cur = temp.substr(0, i) + temp.substr(i + 1);
if (visit.count(cur) == 0) {
q.push(cur);
visit[cur] = 1;
}
}
}
return res;
}
int main() {
string str = "(v)())()";
vector<string> res = validParenthesis(str);
for (string s : res) {
cout << s << endl;
}
return 0;
}
Java
import java.util.*;
class GfG {
// method returns true if string
// contains valid parenthesis
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);
}
// function to remove invalid parenthesis
static List<String> validParenthesis(String str) {
// to ignore already visited string
HashMap<String, Integer> visit = new HashMap<>();
// queue to maintain BFS
Queue<String> q = new LinkedList<>();
// to store the valid strings
List<String> res = new ArrayList<>();
boolean level = false;
// pushing given string as starting node into queue
q.add(str);
// mark the string as visited
visit.put(str, 1);
// while queue is not empty
while (!q.isEmpty()) {
String temp = q.poll();
// check if the string is valid
if (isValidString(temp)) {
// if valid, store it
res.add(temp);
// make level true, so that valid string
// of only that level are processed.
level = true;
}
if (level)
continue;
for (int i = 0; i < temp.length(); i++) {
// if current character is not a parenthesis
// continue to next character
if (temp.charAt(i) != '(' && temp.charAt(i) != ')')
continue;
// Removing parenthesis from str and
// pushing into queue,if not visited already
String cur = temp.substring(0, i) + temp.substring(i + 1);
if (!visit.containsKey(cur)) {
q.add(cur);
visit.put(cur, 1);
}
}
}
return res;
}
public static void main(String[] args) {
String str = "(v)())()";
List<String> res = validParenthesis(str);
for (String s : res) {
System.out.println(s);
}
}
}
Python
from collections import deque
# method returns true if string
# contains valid parenthesis
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
# function to remove invalid parenthesis
def validParenthesis(str):
# to ignore already visited string
visit = {}
# queue to maintain BFS
q = deque()
# to store the valid strings
res = []
level = False
# pushing given string as starting node into queue
q.append(str)
# mark the string as visited
visit[str] = 1
# while queue is not empty
while q:
temp = q.popleft()
# check if the string is valid
if isValidString(temp):
# if valid, store it
res.append(temp)
# make level true, so that valid string
# of only that level are processed.
level = True
if level:
continue
for i in range(len(temp)):
# if current character is not a parenthesis
# continue to next character
if temp[i] != '(' and temp[i] != ')':
continue
# Removing parenthesis from str and
# pushing into queue,if not visited already
cur = temp[:i] + temp[i + 1:]
if cur not in visit:
q.append(cur)
visit[cur] = 1
return res
str = "(v)())()"
res = validParenthesis(str)
for s in res:
print(s)
C#
using System;
using System.Collections.Generic;
class GfG {
// method returns true if string
// contains valid parenthesis
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;
}
// function to remove invalid parenthesis
static List<string> validParenthesis(string str) {
// to ignore already visited string
Dictionary<string, int> visit = new Dictionary<string, int>();
// queue to maintain BFS
Queue<string> q = new Queue<string>();
// to store the valid strings
List<string> res = new List<string>();
bool level = false;
// pushing given string as starting node into queue
q.Enqueue(str);
// mark the string as visited
visit[str] = 1;
// while queue is not empty
while (q.Count > 0) {
string temp = q.Dequeue();
// check if the string is valid
if (isValidString(temp)) {
// if valid, store it
res.Add(temp);
// make level true, so that valid string
// of only that level are processed.
level = true;
}
if (level)
continue;
for (int i = 0; i < temp.Length; i++) {
// if current character is not a parenthesis
// continue to next character
if (temp[i] != '(' && temp[i] != ')')
continue;
// Removing parenthesis from str and
// pushing into queue,if not visited already
string cur = temp.Substring(0, i) + temp.Substring(i + 1);
if (!visit.ContainsKey(cur)) {
q.Enqueue(cur);
visit[cur] = 1;
}
}
}
return res;
}
static void Main() {
string str = "(v)())()";
List<string> res = validParenthesis(str);
foreach (string s in res) {
Console.WriteLine(s);
}
}
}
JavaScript
// method returns true if string
// contains valid parenthesis
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 to remove invalid parenthesis
function validParenthesis(str) {
// to ignore already visited string
let visit = {};
// queue to maintain BFS
let q = [];
// to store the valid strings
let res = [];
let level = false;
// pushing given string as starting node into queue
q.push(str);
// mark the string as visited
visit[str] = 1;
// while queue is not empty
while (q.length > 0) {
let temp = q.shift();
// check if the string is valid
if (isValidString(temp)) {
// if valid, store it
res.push(temp);
// make level true, so that valid string
// of only that level are processed.
level = true;
}
if (level)
continue;
for (let i = 0; i < temp.length; i++) {
// if current character is not a parenthesis
// continue to next character
if (temp[i] !== '(' && temp[i] !== ')')
continue;
// Removing parenthesis from str and
// pushing into queue,if not visited already
let cur = temp.substring(0, i) + temp.substring(i + 1);
if (!(cur in visit)) {
q.push(cur);
visit[cur] = 1;
}
}
}
return res;
}
let str = "(v)())()";
let res = validParenthesis(str);
for (let s of res) {
console.log(s);
}
Time Complexity: O(2 ^ n), the worst‐case time complexity is exponential, namely O(2ⁿ), since BFS may explore up to two options (remove or keep) at each of the n positions.
Space Complexity: O(2 ^ n), since both the BFS queue and the visited‐strings set can each grow to store up to 2ⁿ distinct strings.
Using Depth First Search - O(2 ^ n) Time and O(2 ^ n) Space
We first determine how many opening (
and closing )
parentheses are invalid and need to be removed. Then, use a recursive function to explore all ways of removing these parentheses while maintaining balance between open and close brackets. At each step, either skip a parenthesis (if it's invalid) or include it in the current string (if it helps form a valid expression), and continue building the string. Only strings that end with no unmatched parentheses are collected as valid results.
Below is given the step-by-step approach:
- Count how many open
(
and close )
parentheses are invalid in the input string str
. - Create a set
result
to store all valid strings without duplicates. - Define a recursive function
findValid
that:- Takes current index, counts of invalid open and close parentheses, currently unmatched open pairs (
pair
), the current constructed string cur
, and the result set res
. - If the current character is not a parenthesis, simply add it to
cur
and move to the next index. - If the current character is
(
:- If invalid open count is more than zero, skip this character and decrement
open
. - Also, try including it and increment the
pair
count.
- If the current character is
)
:- If invalid close count is more than zero, skip this character and decrement
close
. - If
pair
is more than zero, include this character and decrement pair
.
- If end of string is reached, check if all invalid counts (
open
, close
) and pair
are zero. If so, add cur
to the result set.
- After recursion completes, convert the result set to a list and return it.
Below is given the implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// recursive function to find all valid strings
void findValid(string str, int index, int open, int close,
int pair, string cur, unordered_set<string> &res) {
// base case, if end of string is reached
if (index == str.size()) {
// check if all open and closed invalid
// parenthesis are removed and no pair is left
if (open == 0 && close == 0 && pair == 0) {
// if so, store the string
res.insert(cur);
}
return;
}
// if the current character is not a parenthesis
if (str[index] != '(' && str[index] != ')') {
// add the character to the current string
findValid(str, index + 1, open, close,
pair, cur + str[index], res);
}
else {
// if the current character is an open bracket
if (str[index] == '(') {
// reduce open count by 1,
// and skip current character
if (open > 0) {
findValid(str, index + 1, open - 1,
close, pair, cur, res);
}
// add the current character to the string
findValid(str, index + 1, open, close,
pair + 1, cur + str[index], res);
}
// else if the current character is a closed bracket
else {
// skip current character and
// reduce closed count by 1
if (close > 0)
findValid(str, index + 1, open,
close - 1, pair, cur, res);
// if there is an open pair, reduce
// it and add the current character
if (pair > 0)
findValid(str, index + 1, open, close,
pair - 1, cur + str[index], res);
}
}
}
vector<string> validParenthesis(string &str) {
// to store the unique valid strings
unordered_set<string> result;
// to store count of invalid
// open and closed paraenthesis
int open = 0, close = 0;
// count the number of invalid
// open and closed parenthesis
for (auto c : str) {
// if open bracket, increase
// open invalid count by 1
if (c == '(')
open++;
// if closed bracket,
if (c == ')') {
// decrement invalid open
// count by 1 if open is not 0
if (open != 0)
open--;
// else increment invalid closed
// bracket count by 1
else
close++;
}
}
// recursive function to find all valid strings
findValid(str, 0, open, close, 0, "", result);
// store the unique strings in an array
vector<string> res(result.begin(), result.end());
return res;
}
int main() {
string str = "(v)())()";
vector<string> res = validParenthesis(str);
for (string s : res) {
cout << s << endl;
}
return 0;
}
Java
import java.util.*;
public class GfG {
// recursive function to find all valid strings
public static void findValid(String str, int index, int open, int close,
int pair, String cur, Set<String> res) {
// base case, if end of string is reached
if (index == str.length()) {
// check if all open and closed invalid
// parenthesis are removed and no pair is left
if (open == 0 && close == 0 && pair == 0) {
// if so, store the string
res.add(cur);
}
return;
}
// if the current character is not a parenthesis
if (str.charAt(index) != '(' && str.charAt(index) != ')') {
// add the character to the current string
findValid(str, index + 1, open, close,
pair, cur + str.charAt(index), res);
}
else {
// if the current character is an open bracket
if (str.charAt(index) == '(') {
// reduce open count by 1,
// and skip current character
if (open > 0) {
findValid(str, index + 1, open - 1,
close, pair, cur, res);
}
// add the current character to the string
findValid(str, index + 1, open, close,
pair + 1, cur + str.charAt(index), res);
}
// else if the current character is a closed bracket
else {
// skip current character and
// reduce closed count by 1
if (close > 0)
findValid(str, index + 1, open,
close - 1, pair, cur, res);
// if there is an open pair, reduce
// it and add the current character
if (pair > 0)
findValid(str, index + 1, open, close,
pair - 1, cur + str.charAt(index), res);
}
}
}
public static List<String> validParenthesis(String str) {
// to store the unique valid strings
Set<String> result = new HashSet<>();
// to store count of invalid
// open and closed paraenthesis
int open = 0, close = 0;
// count the number of invalid
// open and closed parenthesis
for (char c : str.toCharArray()) {
// if open bracket, increase
// open invalid count by 1
if (c == '(')
open++;
// if closed bracket,
if (c == ')') {
// decrement invalid open
// count by 1 if open is not 0
if (open != 0)
open--;
// else increment invalid closed
// bracket count by 1
else
close++;
}
}
// recursive function to find all valid strings
findValid(str, 0, open, close, 0, "", result);
// store the unique strings in an array
List<String> res = new ArrayList<>(result);
return res;
}
public static void main(String[] args) {
String str = "(v)())()";
List<String> res = validParenthesis(str);
for (String s : res) {
System.out.println(s);
}
}
}
Python
# recursive function to find all valid strings
def findValid(str, index, open, close,
pair, cur, res):
# base case, if end of string is reached
if index == len(str):
# check if all open and closed invalid
# parenthesis are removed and no pair is left
if open == 0 and close == 0 and pair == 0:
# if so, store the string
res.add(cur)
return
# if the current character is not a parenthesis
if str[index] != '(' and str[index] != ')':
# add the character to the current string
findValid(str, index + 1, open, close,
pair, cur + str[index], res)
else:
# if the current character is an open bracket
if str[index] == '(':
# reduce open count by 1,
# and skip current character
if open > 0:
findValid(str, index + 1, open - 1,
close, pair, cur, res)
# add the current character to the string
findValid(str, index + 1, open, close,
pair + 1, cur + str[index], res)
# else if the current character is a closed bracket
else:
# skip current character and
# reduce closed count by 1
if close > 0:
findValid(str, index + 1, open,
close - 1, pair, cur, res)
# if there is an open pair, reduce
# it and add the current character
if pair > 0:
findValid(str, index + 1, open, close,
pair - 1, cur + str[index], res)
def validParenthesis(str):
# to store the unique valid strings
result = set()
# to store count of invalid
# open and closed paraenthesis
open = 0
close = 0
# count the number of invalid
# open and closed parenthesis
for c in str:
# if open bracket, increase
# open invalid count by 1
if c == '(':
open += 1
# if closed bracket,
if c == ')':
# decrement invalid open
# count by 1 if open is not 0
if open != 0:
open -= 1
# else increment invalid closed
# bracket count by 1
else:
close += 1
# recursive function to find all valid strings
findValid(str, 0, open, close, 0, "", result)
# store the unique strings in an array
return list(result)
if __name__ == "__main__":
str = "(v)())()"
res = validParenthesis(str)
for s in res:
print(s)
C#
using System;
using System.Collections.Generic;
public class GfG {
// recursive function to find all valid strings
public static void findValid(string str, int index, int open, int close,
int pair, string cur, HashSet<string> res) {
// base case, if end of string is reached
if (index == str.Length) {
// check if all open and closed invalid
// parenthesis are removed and no pair is left
if (open == 0 && close == 0 && pair == 0) {
// if so, store the string
res.Add(cur);
}
return;
}
// if the current character is not a parenthesis
if (str[index] != '(' && str[index] != ')') {
// add the character to the current string
findValid(str, index + 1, open, close,
pair, cur + str[index], res);
}
else {
// if the current character is an open bracket
if (str[index] == '(') {
// reduce open count by 1,
// and skip current character
if (open > 0) {
findValid(str, index + 1, open - 1,
close, pair, cur, res);
}
// add the current character to the string
findValid(str, index + 1, open, close,
pair + 1, cur + str[index], res);
}
// else if the current character is a closed bracket
else {
// skip current character and
// reduce closed count by 1
if (close > 0)
findValid(str, index + 1, open,
close - 1, pair, cur, res);
// if there is an open pair, reduce
// it and add the current character
if (pair > 0)
findValid(str, index + 1, open, close,
pair - 1, cur + str[index], res);
}
}
}
public static List<string> validParenthesis(string str) {
// to store the unique valid strings
HashSet<string> result = new HashSet<string>();
// to store count of invalid
// open and closed paraenthesis
int open = 0, close = 0;
// count the number of invalid
// open and closed parenthesis
foreach (char c in str) {
// if open bracket, increase
// open invalid count by 1
if (c == '(')
open++;
// if closed bracket,
if (c == ')') {
// decrement invalid open
// count by 1 if open is not 0
if (open != 0)
open--;
// else increment invalid closed
// bracket count by 1
else
close++;
}
}
// recursive function to find all valid strings
findValid(str, 0, open, close, 0, "", result);
// store the unique strings in an array
List<string> res = new List<string>(result);
return res;
}
public static void Main() {
string str = "(v)())()";
List<string> res = validParenthesis(str);
foreach (string s in res) {
Console.WriteLine(s);
}
}
}
JavaScript
// recursive function to find all valid strings
function findValid(str, index, open, close,
pair, cur, res) {
// base case, if end of string is reached
if (index === str.length) {
// check if all open and closed invalid
// parenthesis are removed and no pair is left
if (open === 0 && close === 0 && pair === 0) {
// if so, store the string
res.add(cur);
}
return;
}
// if the current character is not a parenthesis
if (str[index] !== '(' && str[index] !== ')') {
// add the character to the current string
findValid(str, index + 1, open, close,
pair, cur + str[index], res);
}
else {
// if the current character is an open bracket
if (str[index] === '(') {
// reduce open count by 1,
// and skip current character
if (open > 0) {
findValid(str, index + 1, open - 1,
close, pair, cur, res);
}
// add the current character to the string
findValid(str, index + 1, open, close,
pair + 1, cur + str[index], res);
}
// else if the current character is a closed bracket
else {
// skip current character and
// reduce closed count by 1
if (close > 0)
findValid(str, index + 1, open,
close - 1, pair, cur, res);
// if there is an open pair, reduce
// it and add the current character
if (pair > 0)
findValid(str, index + 1, open, close,
pair - 1, cur + str[index], res);
}
}
}
function validParenthesis(str) {
// to store the unique valid strings
let result = new Set();
// to store count of invalid
// open and closed paraenthesis
let open = 0, close = 0;
// count the number of invalid
// open and closed parenthesis
for (let c of str) {
// if open bracket, increase
// open invalid count by 1
if (c === '(')
open++;
// if closed bracket,
if (c === ')') {
// decrement invalid open
// count by 1 if open is not 0
if (open !== 0)
open--;
// else increment invalid closed
// bracket count by 1
else
close++;
}
}
// recursive function to find all valid strings
findValid(str, 0, open, close, 0, "", result);
// store the unique strings in an array
return Array.from(result);
}
let str = "(v)())()";
let res = validParenthesis(str);
for (let s of res) {
console.log(s);
}
Similar Reads
Mastering Bracket Problems for Competitive Programming Bracket problems in programming typically refer to problems that involve working with parentheses, and/or braces in expressions or sequences. It typically refers to problems related to the correct and balanced usage of parentheses, and braces in expressions or code. These problems often involve chec
4 min read
Check for balanced with only one type of brackets Given a string str of length N, consisting of '(' and ')' only, the task is to check whether it is balanced or not.Examples:Input: str = "((()))()()" Output: BalancedInput: str = "())((())" Output: Not Balanced Approach 1: Declare a Flag variable which denotes expression is balanced or not.Initialis
9 min read
Valid Parentheses in an Expression Given a string s representing an expression containing various types of brackets: {}, (), and [], the task is to determine whether the brackets in the expression are balanced or not. A balanced expression is one where every opening bracket has a corresponding closing bracket in the correct order.Exa
8 min read
Length of longest balanced parentheses prefix Given a string of open bracket '(' and closed bracket ')'. The task is to find the length of longest balanced prefix. Examples: Input : S = "((()())())((" Output : 10From index 0 to index 9, they are forming a balanced parentheses prefix.Input : S = "()(())((()"Output : 6The idea is take value of op
9 min read
Modify a numeric string to a balanced parentheses by replacements Given a numeric string S made up of characters '1', '2' and '3' only, the task is to replace characters with either an open bracket ( '(' ) or a closed bracket ( ')' ) such that the newly formed string becomes a balanced bracket sequence. Note: All occurrences of a character must be replaced by the
10 min read
Check if the bracket sequence can be balanced with at most one change in the position of a bracket Given an unbalanced bracket sequence as a string str, the task is to find whether the given string can be balanced by moving at most one bracket from its original place in the sequence to any other position.Examples: Input: str = ")(()" Output: Yes As by moving s[0] to the end will make it valid. "(
6 min read
Number of closing brackets needed to complete a regular bracket sequence Given an incomplete bracket sequence S. The task is to find the number of closing brackets ')' needed to make it a regular bracket sequence and print the complete bracket sequence. You are allowed to add the brackets only at the end of the given bracket sequence. If it is not possible to complete th
7 min read
Minimum number of Parentheses to be added to make it valid Given a string S of parentheses '(' or ')' where, 0\leq len(S)\leq 1000 . The task is to find a minimum number of parentheses '(' or ')' (at any positions) we must add to make the resulting parentheses string is valid. Examples: Input: str = "())" Output: 1 One '(' is required at beginning. Input: s
9 min read
Minimum bracket reversals to make an expression balanced Given an expression with only '}' and '{'. The expression may not be balanced. Find minimum number of bracket reversals to make the expression balanced.Examples: Input: s = "}{{}}{{{"Output: 3Explanation: We need to reverse minimum 3 brackets to make "{{{}}{}}". Input: s = "{{"Output: 1Explanation:
15+ min read
Find the number of valid parentheses expressions of given length Given a number n, the task is to find the number of valid parentheses expressions of that length. Examples : Input: 2Output: 1 Explanation: There is only possible valid expression of length 2, "()"Input: 4Output: 2 Explanation: Possible valid expression of length 4 are "(())" and "()()" Input: 6Outp
11 min read