1963. Minimum Number of Swaps to Make The String Balanced - Explanation
Description
You are given a 0-indexed string s of even length n. The string consists of exactly n / 2 opening brackets '[' and n / 2 closing brackets ']'.
A string is called balanced if and only if:
- It is the empty string, or
- It can be written as
AB, where bothAandBare balanced strings, or - It can be written as
[C], whereCis a balanced string.
You may swap the brackets at any two indices any number of times.
Return the minimum number of swaps to make s balanced.
Example 1:
Input: s = "][]["
Output: 1Explanation: You can make the string balanced by swapping index 0 with index 3.
The resulting string is "[[]]".
Example 2:
Input: s = "]]][[["
Output: 2Explanation: You can do the following to make the string balanced:
- Swap index 0 with index 4. s = "[]][][".
- Swap index 1 with index 5. s = "[[][]]".
The resulting string is "[[][]]".
Example 3:
Input: s = "[]"
Output: 0Explanation: The string is already balanced.
Constraints:
n == s.length2 <= n <= 1,000,000nis even.s[i]is either'['or']'.- The number of opening brackets
'['equalsn / 2, and the number of closing brackets']'equalsn / 2.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Stack Data Structure - Used to track unmatched opening brackets during traversal
- Bracket Matching - Understanding how to pair opening and closing brackets in sequence
- Greedy Algorithms - The optimal solutions use greedy reasoning to count minimum swaps needed
1. Stack
Intuition
A balanced string has every ] matched with a preceding [. We use a stack to track unmatched opening brackets. When we see [, we push it. When we see ] and the stack is not empty, we pop (the bracket is matched). If the stack is empty when we see ], that closing bracket is unmatched.
After processing, the stack contains only unmatched [ brackets. Since the string has equal counts of [ and ], the number of unmatched [ equals the number of unmatched ]. Each swap fixes two unmatched pairs, so we need (unmatched + 1) / 2 swaps.
Algorithm
- Initialize an empty
stack. - Iterate through the string:
- If the character is
[, push it onto thestack. - If the character is
]and thestackis not empty, pop thestack.
- If the character is
- The remaining
stacksize represents unmatched[brackets. - Return
(stack_size + 1) / 2.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Greedy - I
Intuition
Instead of tracking opening brackets, we can track the imbalance directly. We maintain a close counter that increases for ] and decreases for [. The max value this counter reaches tells us the worst-case imbalance, meaning the maximum number of unmatched closing brackets at any point.
Since each swap can fix at most 2 unmatched brackets, the number of swaps needed is (max_imbalance + 1) / 2.
Algorithm
- Initialize
close = 0andmaxClose = 0. - Iterate through the string:
- If the character is
[, decrementclose. - If the character is
], incrementclose. - Update
maxClose = max(maxClose, close).
- If the character is
- Return
(maxClose + 1) / 2.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Greedy - II
Intuition
This approach directly simulates the stack without actually using a stack data structure. We use a counter stackSize that increments for [ and decrements for ] only if there is something to match (stackSize > 0). The final counter value represents unmatched opening brackets.
This is equivalent to the stack approach but uses O(1) space since we only track the count, not the actual characters.
Algorithm
- Initialize
stackSize = 0. - Iterate through the string:
- If the character is
[, incrementstackSize. - If the character is
]andstackSize > 0, decrementstackSize.
- If the character is
- Return
(stackSize + 1) / 2.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Counting All Brackets Instead of Unmatched
The answer depends on unmatched brackets, not total brackets. Counting all [ or ] characters without first matching valid pairs will give an incorrect count. Only brackets that remain after matching contribute to the swap count.
Forgetting That One Swap Fixes Two Pairs
Each swap can fix two unmatched bracket pairs simultaneously. Returning the unmatched count directly instead of dividing by 2 (with ceiling) will double the actual number of swaps needed.
Popping From Empty Stack
When simulating with a stack, attempting to pop when encountering ] without checking if the stack is empty will cause runtime errors. Only pop if there is a matching [ available to pair with the current ].
Sign in to join the discussion