Minimum Add to Make Parentheses Valid

MediumGreedy · Balance Counting🧩 GreedyLeetCode #921 ↗Updated

Problem

A string s contains only '(' and ')'. In one move you may insert a single parenthesis anywhere. Return the fewest insertions that turn s into a balanced string (every opener closed later, in proper nesting).
Inputs = "())"Output1
Inputs = "((("Output3
Inputs = "()))(("Output4

1 ≤ s.length ≤ 1000  ·  s[i] is '(' or ')'

Try it yourself

Java
class Solution {
    public int minAddToMakeValid(String s) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Scan left to right with a counter of unmatched '('. A ')' with nothing to match needs an inserted '(' right now; whatever openers are still unmatched at the end each need a ')'.
PatternGreedy

Instinct An optimisation where one obvious local rule (earliest end, farthest reach, biggest first) never needs undoing - commit to it, then try hard to break it.

Memory hack Grab the best bite now and never look back - but only once a counterexample hunt fails to make you regret it.

Open the Greedy guide →

Approaches

Brute ForceCancel () Pairs Until None Remain

Time O(n2)Space O(n)

Every adjacent "()" is already a matched pair, so delete them and repeat until no pair is left. What survives looks like ")))(((" — none of it can match anything, so each leftover character needs exactly one insertion.

Java
public int minAddToMakeValid(String s) {
    String cur = s;
    while (cur.contains("()")) {
        cur = cur.replace("()", ""); // remove all adjacent matched pairs
    }
    return cur.length(); // leftovers look like ")))((("
}

Intuitive picture of matching, but each pass rebuilds the string.

At a glance

LevelApproachTimeSpace
Brute ForceCancel () Pairs Until None RemainO(n2)O(n)
BetterStack of Unmatched CharactersO(n)O(n)
OptimalTwo CountersO(n)O(1)
Common pitfalls
  • Returning |#'(' - #')'| — ")(" has equal counts but needs 2.
  • Letting open go negative instead of counting an orphan ')' separately.
  • Forgetting the openers still unmatched at the end of the scan.
Interview tips
  • Show ")(" early to prove that order matters, not just counts.
  • Explain why the greedy choice (insert a '(' immediately) is never worse than delaying.
  • Contrast with Valid Parentheses: multiple bracket types genuinely need the stack.
Pattern
Balance counter → single bracket type: replace the stack with a running count of unmatched openers.
My notes saved in this browser