|
| 1 | +## Explanation |
| 2 | + |
| 3 | +### Strategy (The "Why") |
| 4 | + |
| 5 | +**1.1 Constraints & Complexity:** |
| 6 | + |
| 7 | +- **Input Size:** `1 <= s.length <= 10^5`. |
| 8 | +- **Characters:** `s[i]` is either '(', ')', or a lowercase English letter. |
| 9 | +- **Time Complexity:** O(n) - we make two passes through the string. |
| 10 | +- **Space Complexity:** O(n) - we use a stack and a set to track indices to remove. |
| 11 | +- **Edge Case:** If the string has no parentheses, return the original string. If all parentheses are invalid, return only the letters. |
| 12 | + |
| 13 | +**1.2 High-level approach:** |
| 14 | + |
| 15 | +The goal is to remove the minimum number of parentheses to make the string valid. We use a two-pass approach: first, identify invalid parentheses using a stack, then build the result string by skipping those indices. |
| 16 | + |
| 17 | +![Visualization showing how a stack is used to match parentheses and identify invalid ones that need to be removed] |
| 18 | + |
| 19 | +**1.3 Brute force vs. optimized strategy:** |
| 20 | + |
| 21 | +- **Brute Force:** Try all possible combinations of removing parentheses and check validity. This is exponential. |
| 22 | +- **Optimized Strategy:** Use a stack to identify unmatched parentheses in one pass, then build the result in a second pass. This takes O(n) time. |
| 23 | +- **Why it's better:** The stack-based approach efficiently identifies invalid parentheses in linear time, which is optimal for this problem. |
| 24 | + |
| 25 | +**1.4 Decomposition:** |
| 26 | + |
| 27 | +1. First pass: Use a stack to track opening parentheses indices. |
| 28 | +2. When encountering ')', if stack is empty, mark this ')' for removal. Otherwise, pop from stack (matched pair). |
| 29 | +3. After first pass, any remaining indices in the stack are unmatched '(' and should be removed. |
| 30 | +4. Second pass: Build the result string by skipping indices marked for removal. |
| 31 | +5. Return the result string. |
| 32 | + |
| 33 | +### Steps (The "How") |
| 34 | + |
| 35 | +**2.1 Initialization & Example Setup:** |
| 36 | + |
| 37 | +Let's use the example: `s = "lee(t(c)o)de)"`. |
| 38 | + |
| 39 | +We initialize: |
| 40 | +- `stack = []` |
| 41 | +- `to_remove = set()` |
| 42 | + |
| 43 | +**2.2 Start Checking:** |
| 44 | + |
| 45 | +First pass: Identify invalid parentheses. |
| 46 | + |
| 47 | +**2.3 Trace Walkthrough:** |
| 48 | + |
| 49 | +| Step | char | index | Action | stack | to_remove | |
| 50 | +|------|------|-------|--------|-------|-----------| |
| 51 | +| 1 | 'l' | 0 | Letter, skip | [] | {} | |
| 52 | +| 2 | 'e' | 1 | Letter, skip | [] | {} | |
| 53 | +| 3 | 'e' | 2 | Letter, skip | [] | {} | |
| 54 | +| 4 | '(' | 3 | Push index 3 | [3] | {} | |
| 55 | +| 5 | 't' | 4 | Letter, skip | [3] | {} | |
| 56 | +| 6 | '(' | 5 | Push index 5 | [3, 5] | {} | |
| 57 | +| 7 | 'c' | 6 | Letter, skip | [3, 5] | {} | |
| 58 | +| 8 | ')' | 7 | Pop from stack | [3] | {} | |
| 59 | +| 9 | 'o' | 8 | Letter, skip | [3] | {} | |
| 60 | +| 10 | ')' | 9 | Pop from stack | [] | {} | |
| 61 | +| 11 | 'd' | 10 | Letter, skip | [] | {} | |
| 62 | +| 12 | 'e' | 11 | Letter, skip | [] | {} | |
| 63 | +| 13 | ')' | 12 | Stack empty, mark for removal | [] | {12} | |
| 64 | + |
| 65 | +After first pass: |
| 66 | +- `stack = []` (all '(' were matched) |
| 67 | +- `to_remove = {12}` (unmatched ')') |
| 68 | + |
| 69 | +**2.4 Increment and Loop:** |
| 70 | + |
| 71 | +Second pass: Build result string, skipping index 12. |
| 72 | + |
| 73 | +| Index | char | In to_remove? | Add to result? | Result so far | |
| 74 | +|-------|------|---------------|----------------|---------------| |
| 75 | +| 0 | 'l' | No | Yes | "l" | |
| 76 | +| 1 | 'e' | No | Yes | "le" | |
| 77 | +| 2 | 'e' | No | Yes | "lee" | |
| 78 | +| 3 | '(' | No | Yes | "lee(" | |
| 79 | +| 4 | 't' | No | Yes | "lee(t" | |
| 80 | +| 5 | '(' | No | Yes | "lee(t(" | |
| 81 | +| 6 | 'c' | No | Yes | "lee(t(c" | |
| 82 | +| 7 | ')' | No | Yes | "lee(t(c)" | |
| 83 | +| 8 | 'o' | No | Yes | "lee(t(c)o" | |
| 84 | +| 9 | ')' | No | Yes | "lee(t(c)o)" | |
| 85 | +| 10 | 'd' | No | Yes | "lee(t(c)o)d" | |
| 86 | +| 11 | 'e' | No | Yes | "lee(t(c)o)de" | |
| 87 | +| 12 | ')' | Yes | No | "lee(t(c)o)de" | |
| 88 | + |
| 89 | +**2.5 Return Result:** |
| 90 | + |
| 91 | +Return `res = "lee(t(c)o)de"` - the valid string after removing the minimum number of parentheses. |
| 92 | + |
0 commit comments