Open In App

Minimum Additions for Valid Parentheses

Last Updated : 13 Sep, 2025
Comments
Improve
Suggest changes
22 Likes
Like
Report

Given a string s consisting of parentheses '(' and ')'. Find the minimum number of parentheses (either '(' or ')') that must be added at any positions to make the string s a valid parentheses string.

A string is valid if every opening parenthesis has a corresponding closing parenthesis and they are properly nested.

Examples: 

Input: s = "(()("
Output: 2
Explanation: Two '(' are left unmatched, so we need two ')' to balance.

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

[Approach 1] 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

[Approach 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 ')'.

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

[Approach 3] Using Two-Pass Counting Method - O(n) Time and O(1) Space

The idea is to scan the string twice first left to right to count unmatched ')', then right to left to count unmatched '('. The sum of these two counts gives the minimum insertions needed to make the string valid.

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

Article Tags :

Explore