Minimum Additions for Valid Parentheses (original) (raw)

Last Updated : 13 Sep, 2025

Given a string **s consisting of parentheses '(' and ')'. Find the minimum number of parentheses(either '(' or ')') that must be addedat 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.

Try It Yourselfredirect icon

Table of Content

[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:

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

C++ `

#include #include using namespace std;

int minParentheses(string& s) { stack 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 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 st = new Stack();

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

`

[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 #include 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));

`

[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 #include 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));

`