A bracket string of even length consists of exactly n/2 opening [ and n/2 closing ] characters. The goal is to determine fewest number of arbitrary index swaps required to transform the string into a valid bracket sequence (one where every closing bracket has a matching opening bracket earlier in the string).
Pairs of matched brackets can be thought of as canceling each other out. Scanning left to right, whenever a [ is encountered, we increment a counter that tracks unmatched opening brackets. Upon seeeing a ], if the counter is positive, we decrement it—this represents matching the ] with a previous [. If the counter is zero, the ] has no available partner and must be involved in a future swap. This uncanceled ] count is accumulated in a variable unmatchedClose.
After processing the entire string, the remaining unmatched brackets form a pattern consisting of k closing brackets followed by k opening brackets (]]]...[[[). Swapping a closing bracket from the beginning of this pattern with an opening bracket from the end corrects two positions at once. Therefore, the minimal swaps needed are (unmatchedClose + 1) / 2. Integer division by two can be expressed with a right shift for efficiency.
An explicit stack is unnecessary; a simple integer tracker replaces push/pop operations.
public int minSwaps(String s) {
int pendingOpens = 0;
int mismatchedCloses = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '[') {
pendingOpens++;
} else { // ch == ']'
if (pendingOpens > 0) {
pendingOpens--;
} else {
mismatchedCloses++;
}
}
}
return (mismatchedCloses + 1) >>> 1;
}