Open In App

Remove Invalid Parentheses

Last Updated : 08 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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);
}

Output
(v())()
(v)()()

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);
}

Output
(v)()()
(v())()

Next Article
Article Tags :
Practice Tags :

Similar Reads