Program to find minimum remove required to make valid parentheses in Python

When working with parentheses validation, we often need to remove the minimum number of invalid parentheses to make a string valid. A string with parentheses is considered valid when every opening parenthesis has a corresponding closing parenthesis in the correct order.

Problem Statement

Given a string containing parentheses '(' and ')' along with lowercase English characters, we need to remove the minimum number of parentheses to make the string valid. A valid parentheses string satisfies these criteria:

  • The string is empty or contains only lowercase characters, or

  • The string can be written as AB (A concatenated with B), where A and B are valid strings, or

  • The string can be written as (A), where A is a valid string.

Algorithm Approach

We'll use a stack-based approach to track unmatched parentheses:

  • Use a stack to store indices of unmatched opening parentheses

  • Use a set to store indices of invalid parentheses (both unmatched opening and closing)

  • Traverse the string and match parentheses pairs

  • Build the result by excluding invalid parentheses

Implementation

def solve(s):
    stack = []
    invalid_indexes = set()
    
    # First pass: identify unmatched parentheses
    for i, c in enumerate(s):
        if c == '(':
            stack.append(i)
        elif c == ')':
            if len(stack) == 0:
                # Unmatched closing parenthesis
                invalid_indexes.add(i)
            else:
                # Matched pair, remove opening parenthesis from stack
                stack.pop()
    
    # Add remaining unmatched opening parentheses to invalid set
    invalid_indexes = invalid_indexes.union(stack)
    
    # Build result string excluding invalid parentheses
    result = ''
    for i in range(len(s)):
        if i not in invalid_indexes:
            result += s[i]
    
    return result

# Test the function
s = "m)n(o)p"
print(f"Input: {s}")
print(f"Output: {solve(s)}")
Input: m)n(o)p
Output: mn(o)p

Step-by-Step Walkthrough

Let's trace through the example "m)n(o)p":

def solve_with_trace(s):
    stack = []
    invalid_indexes = set()
    
    print(f"Processing string: {s}")
    
    for i, c in enumerate(s):
        print(f"Index {i}, Character '{c}':")
        if c == '(':
            stack.append(i)
            print(f"  Added opening at index {i} to stack: {stack}")
        elif c == ')':
            if len(stack) == 0:
                invalid_indexes.add(i)
                print(f"  Unmatched closing at index {i}, added to invalid: {invalid_indexes}")
            else:
                popped = stack.pop()
                print(f"  Matched with opening at index {popped}")
        else:
            print(f"  Regular character, skipping")
    
    print(f"Remaining unmatched opening parentheses: {stack}")
    invalid_indexes = invalid_indexes.union(stack)
    print(f"All invalid indexes: {invalid_indexes}")
    
    result = ''.join(s[i] for i in range(len(s)) if i not in invalid_indexes)
    return result

# Trace example
result = solve_with_trace("m)n(o)p")
print(f"Final result: {result}")
Processing string: m)n(o)p
Index 0, Character 'm':
  Regular character, skipping
Index 1, Character ')':
  Unmatched closing at index 1, added to invalid: {1}
Index 2, Character 'n':
  Regular character, skipping
Index 3, Character '(':
  Added opening at index 3 to stack: [3]
Index 4, Character 'o':
  Regular character, skipping
Index 5, Character ')':
  Matched with opening at index 3
Index 6, Character 'p':
  Regular character, skipping
Remaining unmatched opening parentheses: []
All invalid indexes: {1}
Final result: mn(o)p

Time and Space Complexity

  • Time Complexity: O(n) where n is the length of the string

  • Space Complexity: O(n) for the stack and invalid indexes set

Conclusion

This stack-based approach efficiently identifies and removes the minimum number of invalid parentheses. The algorithm ensures that all remaining parentheses are properly matched while preserving the original order of characters.

---
Updated on: 2026-03-26T14:38:29+05:30

493 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements