Minimum Additions for Valid Parentheses

Last Updated : 29 Jul, 2026

Given a stringĀ sĀ consistingĀ only of the charactersĀ '('Ā andĀ ')'. Your task is to determine theĀ minimumĀ number of parentheses (either '(' or ')') that must be inserted at any positions to make the string s a valid parentheses string.

A parentheses string is considered valid if:

  1. Every opening parenthesis '(' has a corresponding closing parenthesis ')'.
  2. Every closing parenthesis ')' has a corresponding opening parenthesis '('.
  3. Parentheses are properly nested.

Examples:Ā 

Input: s = "(()("
Output: 2
Explanation: There are two unmatched '(' at the end, so we need to add two ')' to make the string valid.

Input: s = ")))"
Output: 3
Explanation: Three '(' need to be added at the start to make the string valid.

Input: s = ")()()"
Output: 1
Explanation: The very first ')' is unmatched, so we need to add one '(' at the beginning.

Try It Yourself
redirect icon

Using Stack - O(n) Time and O(n) Space

The idea is to use the concept of valid parentheses. For every opening parenthesis, a matching closing parenthesis will remove it from the stack. At the end, only the unmatched parentheses remain in the stack, and their count gives the number of insertions needed to make the string valid.

At the end of the string:

  • Every '(' left in the stack needs a ')' to become valid.
  • Every ')' left in the stack needs a '(' to become valid.

Hence, the minimum number of insertions needed = number of unmatched parentheses = stack size.

C++
#include <iostream>
#include <stack>
using namespace std;

int minParentheses(string& s) {
    stack<char> st;
    
    for (int i = 0; i < s.size(); i++) {
        if (!st.empty()) {
            if (s[i] == '(')
                st.push('(');
            else if (st.top() == '(')
            
                // matched pair, remove from stack
                st.pop();
            else
            
            // unmatched closing parenthesis
                st.push(s[i]);
        } else {
            st.push(s[i]);
        }
    }
    return st.size();
}

int main() {
    string s = "(()(";
    cout << minParentheses(s);  
}
Java
import java.util.Stack;

public class GfG {
    static int minParentheses(String s) {
        Stack<Character> st = new Stack<>();
        
        for (int i = 0; i < s.length(); i++) {
            if (!st.isEmpty()) {
                if (s.charAt(i) == '(')
                    st.push('(');
                else if (st.peek() == '(')
               
                    // matched pair, remove from stack
                    st.pop();
                else
               
                    // unmatched closing parenthesis
                    st.push(s.charAt(i));
            } else {
                st.push(s.charAt(i));
            }
        }
        return st.size();
    }

    public static void main(String[] args) {
        String s = "(()(";
        System.out.println(minParentheses(s));
    }
}
Python
def minParentheses(s):
    st = []
    
    for i in range(len(s)):
        if st:
            if s[i] == '(':
                st.append('(')
            elif st[-1] == '(':
           
                # matched pair, remove from stack
                st.pop()
            else:
           
                # unmatched closing parenthesis
                st.append(s[i])
        else:
            st.append(s[i])
    return len(st)

if __name__ == "__main__":
    s = "(()("
    print(minParentheses(s))
C#
using System;
using System.Collections.Generic;

public class GfG {
    static int minParentheses(string s) {
        Stack<char> st = new Stack<char>();
        
        for (int i = 0; i < s.Length; i++) {
            if (st.Count > 0) {
                if (s[i] == '(')
                    st.Push('(');
                else if (st.Peek() == '(')
            
                    // matched pair, remove from stack
                    st.Pop();
                else
            
                    // unmatched closing parenthesis
                    st.Push(s[i]);
            } else {
                st.Push(s[i]);
            }
        }
        return st.Count;
    }

    public static void Main() {
        string s = "(()(";
        Console.WriteLine(minParentheses(s));
    }
}
JavaScript
function minParentheses(s) {
    let st = [];
    
    for (let i = 0; i < s.length; i++) {
        if (st.length > 0) {
            if (s[i] === '(')
                st.push('(');
            else if (st[st.length - 1] === '(')
          
                // matched pair, remove from stack
                st.pop();
            else
          
                // unmatched closing parenthesis
                st.push(s[i]);
        } else {
            st.push(s[i]);
        }
    }
    return st.length;
}

// Driver Code
let s = "(()(";
console.log(minParentheses(s));

Output
2

Using Counter / Balance Method - O(n) Time and O(1) Space

The idea is to track unmatched parentheses using counters instead of a stack. We keep a balance for unmatched '(' and a counter for unmatched ')'. Whenever balance goes negative, it means there is an extra closing parenthesis, so we increase the unmatched closing counter and reset balance. At the end, the total insertions required is the sum of remaining unmatched '(' and unmatched ')'.

Working of Approach:

  • Traverse the string while maintaining a balance count of unmatched '(' brackets.
  • Increase the balance for every '(' and decrease it for every ')'.
  • If the balance becomes negative, it means a closing bracket has no matching opening bracket. Count it as an unmatched ')' and reset the balance to 0.
  • After the traversal, the remaining balance gives unmatched '(', and adding it to the unmatched ')' count gives the minimum parentheses required to make the string balanced.
C++
#include <iostream>
#include <string>
using namespace std;

int minParentheses(string &s) {
    int balance = 0; 
    int unmatchedClosing = 0;   

    for (int i = 0; i < s.size(); ++i) {
        
        // if current char is '(', increment balance
        if (s[i] == '(') {
            balance++;           
        } 
        // if current char is ')', decrement balance
        else if (s[i] == ')') {
            balance--;           

            // if balance becomes negative, unmatched ')'
            if (balance < 0) {
                
                // increment unmatched closing counter
                unmatchedClosing++;
                balance = 0;     
            }
        }
    }

    // total additions = remaining '(' + unmatched ')'
    return balance + unmatchedClosing;
}

int main() {
    string s ="(()(";
    cout << minParentheses(s) << endl;
    return 0;
}
Java
public class GfG {

    static int minParentheses(String s) {
        int balance = 0;
        int unmatchedClosing = 0;

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            // if current char is '(', increment balance
            if (c == '(') {
                balance++;
            } 
            // if current char is ')', decrement balance
            else if (c == ')') {
                balance--;

                // if balance becomes negative, unmatched ')'
                if (balance < 0) {
                    unmatchedClosing++;
                    balance = 0;
                }
            }
        }

        // total additions = remaining '(' + unmatched ')'
        return balance + unmatchedClosing;
    }

    public static void main(String[] args) {
        String s = "(()(";
        System.out.println(minParentheses(s));
    }
}
Python
def minParentheses(s):
    balance = 0
    unmatchedClosing = 0

    for c in s:
      
        # if current char is '(', increment balance
        if c == '(':
            balance += 1
      
        # if current char is ')', decrement balance
        elif c == ')':
            balance -= 1

            # if balance becomes negative, unmatched ')'
            if balance < 0:
      
                # increment unmatched closing counter
                unmatchedClosing += 1
                balance = 0

    # total additions = remaining '(' + unmatched ')'
    return balance + unmatchedClosing

if __name__ == "__main__":
    s = "(()("
    print(minParentheses(s))
C#
using System;

public class GfG {
    static int minParentheses(string s) {
        int balance = 0;
        int unmatchedClosing = 0;

        foreach (char c in s) {
         
            // if current char is '(', increment balance
            if (c == '(') {
                balance++;
            }
         
            // if current char is ')', decrement balance
            else if (c == ')') {
                balance--;

                // if balance becomes negative, unmatched ')'
                if (balance < 0) {
         
                    // increment unmatched closing counter
                    unmatchedClosing++;
                    balance = 0;
                }
            }
        }

        // total additions = remaining '(' + unmatched ')'
        return balance + unmatchedClosing;
    }

    public static void Main(string[] args) {
        string s = "(()(";
        Console.WriteLine(minParentheses(s));
    }
}
JavaScript
function minParentheses(s) {
    let balance = 0;
    let unmatchedClosing = 0;

    for (let c of s) {
     
        // if current char is '(', increment balance
        if (c === '(') {
            balance++;
        }
     
        // if current char is ')', decrement balance
        else if (c === ')') {
            balance--;

            // if balance becomes negative, unmatched ')'
            if (balance < 0) {
                
                // increment unmatched closing counter
                unmatchedClosing++;
                balance = 0;
            }
        }
    }

    // total additions = remaining '(' + unmatched ')'
    return balance + unmatchedClosing;
}

// Driver Code
let s = "(()(";
console.log(minParentheses(s));

Output
2

Using Two-Pass Counting Method - O(n) Time and O(1) Space

The idea is to scan the string twice. The first traversal counts unmatched closing parentheses, while the second traversal counts unmatched opening parentheses. Their sum gives the minimum insertions required.

Working of Approach:

  • Traverse the string from left to right to count unmatched ')' brackets by maintaining the balance of '('. Whenever the balance becomes negative, increment the unmatched closing count and reset the balance.
  • Traverse the string again from right to left to count unmatched '(' brackets by maintaining the balance of ')'. Whenever the balance becomes negative, increment the unmatched opening count and reset the balance.
  • The first traversal identifies extra closing brackets, while the second traversal identifies extra opening brackets.
  • The sum of unmatched opening and unmatched closing brackets gives the minimum number of parentheses that must be added to make the string balanced.
C++
#include <iostream>
#include <string>
using namespace std;

int minParentheses(string &s) {
    int n = s.size();
    int unmatchedClosing = 0;
    int balance = 0;

    // first pass: left to right
    for (int i = 0; i < s.size(); ++i) {
    
        // if current char is '(', increment balance
        if (s[i] == '(') {
            balance++;
        }
        // if current char is ')', decrement balance
        else if (s[i] == ')'){
            balance--;

            // if balance becomes negative, unmatched ')'
            if (balance < 0) {
                unmatchedClosing++;
                balance = 0;
            }
        }
    }

    // second pass: right to left to count unmatched '('
    int unmatchedOpening = 0;
    balance = 0;
    for (int i = n - 1; i >= 0; i--) {
     
        // if current char is ')', increment balance
        if (s[i] == ')') {
            balance++;
        }
     
        // if current char is '(', decrement balance
        else if (s[i] == '(') {
            balance--;

            // if balance becomes negative, unmatched '('
            if (balance < 0) {
                unmatchedOpening++;
                balance = 0;
            }
        }
    }

    // total additions = unmatched ')' + unmatched '('
    return unmatchedClosing + unmatchedOpening;
}

int main() {
    string s = "(()(";
    cout << minParentheses(s) << endl;
    return 0;
}
Java
public class GfG {
    static int minParentheses(String s) {
        int n = s.length();
        int unmatchedClosing = 0;
        int balance = 0;

        // first pass: left to right
        for (int i = 0; i < s.length(); ++i) {
        
            // if current char is '(', increment balance
            if (s.charAt(i) == '(') {
                balance++;
            }
        
            // if current char is ')', decrement balance
            else if (s.charAt(i) == ')') {
                balance--;
        
                // if balance becomes negative, unmatched ')'
                if (balance < 0) {
                    unmatchedClosing++;
                    balance = 0;
                }
            }
        }

        // second pass: right to left to count unmatched '('
        int unmatchedOpening = 0;
        balance = 0;
        
        for (int i = n - 1; i >= 0; i--) {
        
            // if current char is ')', increment balance
            if (s.charAt(i) == ')') {
                balance++;
            }
        
            // if current char is '(', decrement balance
            else if (s.charAt(i) == '(') {
                balance--;
        
                // if balance becomes negative, unmatched '('
                if (balance < 0) {
                    unmatchedOpening++;
                    balance = 0;
                }
            }
        }

        // total additions = unmatched ')' + unmatched '('
        return unmatchedClosing + unmatchedOpening;
    }

    public static void main(String[] args) {
        String s = "(()(";
        System.out.println(minParentheses(s));
    }
}
Python
def minParentheses(s):
    n = len(s)
    unmatchedClosing = 0
    balance = 0

    # first pass: left to right
    for c in s:
  
        # if current char is '(', increment balance
        if c == '(':
            balance += 1
  
        # if current char is ')', decrement balance
        elif c == ')':
            balance -= 1

            # if balance becomes negative, unmatched ')'
            if balance < 0:
                unmatchedClosing += 1
                balance = 0

    # second pass: right to left to count unmatched '('
    unmatchedOpening = 0
    balance = 0
    for c in reversed(s):
  
        # if current char is ')', increment balance
        if c == ')':
            balance += 1
  
        # if current char is '(', decrement balance
        elif c == '(':
            balance -= 1

            # if balance becomes negative, unmatched '('
            if balance < 0:
                unmatchedOpening += 1
                balance = 0

    # total additions = unmatched ')' + unmatched '('
    return unmatchedClosing + unmatchedOpening

if __name__ == "__main__":
    s =  "(()("
    print(minParentheses(s))
C#
using System;

public class GfG {
    static int minParentheses(string s) {
        int n = s.Length;
        int unmatchedClosing = 0;
        int balance = 0;

        // first pass: left to right
        foreach (char c in s) {
     
            // if current char is '(', increment balance
            if (c == '(') {
                balance++;
            }
     
            // if current char is ')', decrement balance
            else if (c == ')') {
                balance--;

                // if balance becomes negative, unmatched ')'
                if (balance < 0) {
                    unmatchedClosing++;
                    balance = 0;
                }
            }
        }

        // second pass: right to left to count unmatched '('
        int unmatchedOpening = 0;
        balance = 0;
        for (int i = n - 1; i >= 0; i--) {
     
            // if current char is ')', increment balance
            if (s[i] == ')') {
                balance++;
            }
     
            // if current char is '(', decrement balance
            else if (s[i] == '(') {
                balance--;

                // if balance becomes negative, unmatched '('
                if (balance < 0) {
                    unmatchedOpening++;
                    balance = 0;
                }
            }
        }

        // total additions = unmatched ')' + unmatched '('
        return unmatchedClosing + unmatchedOpening;
    }

    public static void Main(string[] args) {
        string s =  "(()(";
        Console.WriteLine(minParentheses(s));
    }
}
JavaScript
function minParentheses(s) {
    let n = s.length;
    let unmatchedClosing = 0;
    let balance = 0;

    // first pass: left to right
    for (let c of s) {
      
        // if current char is '(', increment balance
        if (c === '(') {
            balance++;
        }
      
        // if current char is ')', decrement balance
        else if (c === ')') {
            balance--;

            // if balance becomes negative, unmatched ')'
            if (balance < 0) {
                unmatchedClosing++;
                balance = 0;
            }
        }
    }

    // second pass: right to left to count unmatched '('
    let unmatchedOpening = 0;
    balance = 0;
    for (let i = n - 1; i >= 0; i--) {
      
        // if current char is ')', increment balance
        if (s[i] === ')') {
            balance++;
        }
      
        // if current char is '(', decrement balance
        else if (s[i] === '(') {
            balance--;

            // if balance becomes negative, unmatched '('
            if (balance < 0) {
                unmatchedOpening++;
                balance = 0;
            }
        }
    }

    // total additions = unmatched ')' + unmatched '('
    return unmatchedClosing + unmatchedOpening;
}

// Driver Code
let s =  "(()(";
console.log(minParentheses(s));

Output
2
Comment