Loading problems...
TL;DR: Use a stack (or counter) to eliminate all valid bracket pairs, leaving only the mismatched brackets, then calculate the swaps needed based on the count of remaining unbalanced pairs.
The problem asks for the minimum number of swaps required to make a string of opening [ and closing ] brackets balanced. A balanced string follows standard valid parentheses rules (e.g., [[]] or [][]). We are given that the total number of opening and closing brackets is equal, ensuring a solution always exists.
This is a popular interview question, often appearing as LeetCode 1963. It tests your ability to simplify complex string manipulation problems into linear-time validation logic.
A naive brute force approach would treat this as a shortest-path problem on a graph.
textQueue q Set visited q.add(initial_string, swaps=0) while q is not empty: curr, swaps = q.pop() if isBalanced(curr): return swaps for i from 0 to n: for j from i+1 to n: next_str = swap(curr, i, j) if next_str not in visited: q.add(next_str, swaps + 1) visited.add(next_str)
The intuition behind the optimal solution is cancellation. We don't need to simulate the swaps physically. Instead, we only need to quantify how "unbalanced" the string is.
When we process the string using the standard Valid Parentheses logic, we pair every closing bracket ] with the nearest available opening bracket [ before it. If we remove all such valid pairs, we are left with a "reduced" string that cannot be simplified further.
Because the original string has an equal number of [ and ], the reduced string will always follow a specific structure:
].[.For example, ]]][[[.
This reduced form consists of closing brackets followed by opening brackets.
The Key Calculation:
One swap can fix two pairs of mismatched brackets in the optimal case.
Consider the reduced form ]][[.
] with the last [ transforms it into [[]].For a generic reduced string of unmatched pairs (e.g., ]]]...[[[), we need swaps. The formula is:
where integer division is used.
Visual Description:
Imagine iterating through the string. Every time you encounter a [, you place a token on a stack. Every time you encounter a ], you check the stack. If there is a token, you remove it (a valid pair is formed and vanishes). If the stack is empty, that ] is a permanent mismatch in the current configuration. At the end of the traversal, the number of tokens remaining on the stack represents the count of [ that never found a closing partner.

Let's trace the algorithm with Example 2: s = "]]][[[".
stack_size = 0.]): stack_size is 0. No match possible. (Conceptually, this is a mismatch).]): stack_size is 0. No match.]): stack_size is 0. No match.[): Increment stack_size to 1.[): Increment stack_size to 2.[): Increment stack_size to 3.stack_size is 3. This means we have 3 unmatched [ brackets (and implicitly 3 unmatched ]).(3 + 1) / 2 = 2.Trace with s = "][][":
stack_size = 0.] -> No match.[ -> stack_size = 1.] -> Match found! stack_size becomes 0.[ -> stack_size = 1.stack_size is 1.(1 + 1) / 2 = 1.Why does (k + 1) / 2 work?
After removing all valid pairs, the string reduces to the form ]...][...[ with closing brackets followed by opening brackets.
The most efficient way to fix this is to swap the first unmatched ] with the last unmatched [.
] ... [.[ ... ].[ at the beginning and the ] at the end form a valid pair [...] that wraps the remaining substring.cppclass Solution { public: int minSwaps(string s) { // 'stackSize' tracks the number of unmatched opening brackets '[' int stackSize = 0; for (char c : s) { if (c == '[') { stackSize++; } else { // If we encounter ']', we try to match it with a previous '[' if (stackSize > 0) { stackSize--; } // If stackSize is 0, this ']' is unmatched, // but we don't need to track it explicitly for the formula. } } // The number of unmatched pairs is stackSize. // Each swap fixes 2 pairs. // Formula: ceil(stackSize / 2) which is (stackSize + 1) / 2 using integer math. return (stackSize + 1) / 2; } };
javaclass Solution { public int minSwaps(String s) { // 'stackSize' simulates a stack of opening brackets int stackSize = 0; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '[') { stackSize++; } else { // If c is ']', check if we have a matching '[' if (stackSize > 0) { stackSize--; } } } // stackSize now represents the number of unmatched '[' brackets. // We need ceil(stackSize / 2) swaps. return (stackSize + 1) / 2; } }
pythonclass Solution: def minSwaps(self, s: str) -> int: # stack_size tracks the number of unmatched '[' stack_size = 0 for c in s: if c == '[': stack_size += 1 else: # c is ']' if stack_size > 0: stack_size -= 1 # stack_size is the number of remaining unmatched '[' # Return ceil(stack_size / 2) return (stack_size + 1) // 2
stack_size instead of storing characters in a collection. If we used an actual stack data structure, space would be .The Stack - Valid Parentheses Matching pattern is fundamental. Understanding how to track balance with a counter or stack applies directly to:
In all these problems, the core logic revolves around cancelling out valid () or [] pairs and analyzing what remains.