Minimum Swaps for Bracket Balancing
You are given a string of 2N characters consisting of N ‘[‘ brackets and N ‘]’ brackets. A string is considered balanced if it can be represented in the form S2[S1] where S1 and S2 are balanced strings. We can make an unbalanced string balanced by swapping adjacent characters. Calculate the minimum number of swaps necessary to make a string balanced.
Examples:
Input : []][][
Output : 2
First swap: Position 3 and 4
[][]][
Second swap: Position 5 and 6
[][][]
Input : [[][]]
Output : 0
The string is already balanced.
We can solve this problem by using greedy strategies. If the first X characters form a balanced string, we can neglect these characters and continue on. If we encounter a ‘]’ before the required ‘[‘, then we must start swapping elements to balance the string.
Naive Approach
Initialize sum = 0 where sum stores result. Go through the string maintaining a count of the number of ‘[‘ brackets encountered. Reduce this count when we encounter a ‘]’ character. If the count hits negative, then we must start balancing the string.
Let index ‘i’ represent the position we are at. We now move forward to the next ‘[‘ at index j. Increase sum by j – i. Move the ‘[‘ at position j, to position i, and shift all other characters to the right. Set the count back to 1 and continue traversing the string. In the end, ‘sum’ will have the required value.
Code-
C++
#include<bits/stdc++.h>
using namespace std;
int swapCount(string s)
{
int ans=0;
int count=0;
int n=s.size();
for ( int i=0;i<n;i++){
if (s[i]== '[' ){count++;}
else {count--;}
if (count<0){
int j=i+1;
while (j<n){
if (s[j]== '[' ){ break ;}
j++;
}
ans+=j-i;
count=1;
char ch=s[j];
for ( int k=j;k>i;k--){
s[k]=s[k-1];
}
s[i]=ch;
}
}
return ans;
}
int main()
{
string s = "[]][][" ;
cout << swapCount(s) << "\n" ;
s = "[[][]]" ;
cout << swapCount(s) << "\n" ;
return 0;
}
|
Java
public class GFG {
static int swapCount(String s) {
int ans = 0 ;
int count = 0 ;
int n = s.length();
for ( int i = 0 ; i < n; i++) {
if (s.charAt(i) == '[' )
count++;
else
count--;
if (count < 0 ) {
int j = i + 1 ;
while (j < n) {
if (s.charAt(j) == '[' )
break ;
j++;
}
ans += j - i;
count = 1 ;
char ch = s.charAt(j);
StringBuilder newString = new StringBuilder(s);
for ( int k = j; k > i; k--) {
newString.setCharAt(k, s.charAt(k - 1 ));
}
newString.setCharAt(i, ch);
s = newString.toString();
}
}
return ans;
}
public static void main(String[] args) {
String s = "[]][][" ;
System.out.println(swapCount(s));
s = "[[][]]" ;
System.out.println(swapCount(s));
}
}
|
Python3
def swap_count(s):
ans = 0
count = 0
n = len (s)
for i in range (n):
if s[i] = = '[' :
count + = 1
else :
count - = 1
if count < 0 :
j = i + 1
while j < n:
if s[j] = = '[' :
break
j + = 1
ans + = j - i
count = 1
ch = s[j]
for k in range (j, i, - 1 ):
s[k] = s[k - 1 ]
s[i] = ch
return ans
if __name__ = = "__main__" :
s = "[]][]["
print (swap_count( list (s)))
s = "[[][]]"
print (swap_count( list (s)))
|
C#
using System;
class Program
{
static int SwapCount( string s)
{
int ans = 0;
int count = 0;
int n = s.Length;
for ( int i = 0; i < n; i++)
{
if (s[i] == '[' )
{
count++;
}
else
{
count--;
}
if (count < 0)
{
int j = i + 1;
while (j < n)
{
if (s[j] == '[' )
{
break ;
}
j++;
}
ans += j - i;
count = 1;
char ch = s[j];
for ( int k = j; k > i; k--)
{
s = s.Remove(k, 1);
s = s.Insert(k, s[k - 1].ToString());
}
s = s.Remove(i, 1);
s = s.Insert(i, ch.ToString());
}
}
return ans;
}
static void Main( string [] args)
{
string s = "[]][][" ;
Console.WriteLine(SwapCount(s));
s = "[[][]]" ;
Console.WriteLine(SwapCount(s));
}
}
|
Javascript
function GFG(s) {
let ans = 0;
let count = 0;
for (let i = 0; i < s.length; i++) {
if (s[i] === '[' ) {
count++;
}
else {
count--;
}
if (count < 0) {
for (let j = 0; j < i; j++) {
if (s[j] === '[' ) {
ans += i - j;
let temp = s.substring(0, j) + s[i] + s.substring(j + 1, i) + s[j] + s.substring(i + 1);
s = temp;
break ;
}
}
count = 1;
}
}
return ans;
}
let s1 = "[]][][" ;
console.log(GFG(s1));
let s2 = "[[][]]" ;
console.log(GFG(s2));
|
Output-
2
0
Time Complexity = O(N^2), one loop is for traversing the string and another loop in finding the next ‘[‘ when the count becomes less than 0 and making the string ready for the next step
Extra Space = O(1), because no extra space has been used
Optimized approach
We can initially go through the string and store the positions of ‘[‘ in a vector say ‘pos‘. Initialize ‘p’ to 0. We shall use p to traverse the vector ‘pos’. Similar to the naive approach, we maintain a count of encountered ‘[‘ brackets. When we encounter a ‘[‘ we increase the count and increase ‘p’ by 1. When we encounter a ‘]’ we decrease the count. If the count ever goes negative, this means we must start swapping. The element pos[p] tells us the index of the next ‘[‘. We increase the sum by pos[p] – i, where i is the current index. We can swap the elements in the current index and pos[p] and reset the count to 1 and increment p so that it pos[p] indicates to the next ‘[‘.
Since we have converted a step that was O(N) in the naive approach, to an O(1) step, our new time complexity reduces.
Time Complexity = O(N)
Extra Space = O(N)
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
long swapCount(string s)
{
vector< int > pos;
for ( int i = 0; i < s.length(); ++i)
if (s[i] == '[' )
pos.push_back(i);
int count = 0;
int p = 0;
long sum = 0;
for ( int i = 0; i < s.length(); ++i)
{
if (s[i] == '[' )
{
++count;
++p;
}
else if (s[i] == ']' )
--count;
if (count < 0)
{
sum += pos[p] - i;
swap(s[i], s[pos[p]]);
++p;
count = 1;
}
}
return sum;
}
int main()
{
string s = "[]][][" ;
cout << swapCount(s) << "\n" ;
s = "[[][]]" ;
cout << swapCount(s) << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG{
public static long swapCount(String s)
{
Vector<Integer> pos = new Vector<Integer>();
for ( int i = 0 ; i < s.length(); ++i)
if (s.charAt(i) == '[' )
pos.add(i);
int count = 0 ;
int p = 0 ;
long sum = 0 ;
char [] S = s.toCharArray();
for ( int i = 0 ; i < s.length(); ++i)
{
if (S[i] == '[' )
{
++count;
++p;
}
else if (S[i] == ']' )
--count;
if (count < 0 )
{
sum += pos.get(p) - i;
char temp = S[i];
S[i] = S[pos.get(p)];
S[pos.get(p)] = temp;
++p;
count = 1 ;
}
}
return sum;
}
public static void main(String[] args)
{
String s = "[]][][" ;
System.out.println(swapCount(s));
s = "[[][]]" ;
System.out.println(swapCount(s));
}
}
|
Python3
def swapCount(s):
pos = []
for i in range ( len (s)):
if (s[i] = = '[' ):
pos.append(i)
count = 0
p = 0
sum = 0
s = list (s)
for i in range ( len (s)):
if (s[i] = = '[' ):
count + = 1
p + = 1
elif (s[i] = = ']' ):
count - = 1
if (count < 0 ):
sum + = pos[p] - i
s[i], s[pos[p]] = (s[pos[p]],
s[i])
p + = 1
count = 1
return sum
s = "[]][]["
print (swapCount(s))
s = "[[][]]"
print (swapCount(s))
|
C#
using System.IO;
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
static long swapCount( string s)
{
List< int > pos = new List< int >();
for ( int i = 0; i < s.Length; i++)
{
if (s[i] == '[' )
{
pos.Add(i);
}
}
int count = 0;
int p = 0;
long sum = 0;
char [] S = s.ToCharArray();
for ( int i = 0; i < S.Length; i++)
{
if (S[i] == '[' )
{
++count;
++p;
}
else if (S[i] == ']' )
{
--count;
}
if (count < 0)
{
sum += pos[p]-i;
char temp = S[i];
S[i] = S[pos[p]];
S[pos[p]] = temp;
++p;
count = 1;
}
}
return sum;
}
static void Main()
{
string s = "[]][][" ;
Console.WriteLine(swapCount(s));
s = "[[][]]" ;
Console.WriteLine(swapCount(s));
}
}
|
Javascript
<script>
function swapCount(s)
{
let pos = [];
for (let i = 0; i < s.length; ++i)
if (s[i] == '[' )
pos.push(i);
let count = 0;
let p = 0;
let sum = 0;
let S = s.split( '' );
for (let i = 0; i < s.length; ++i)
{
if (S[i] == '[' )
{
++count;
++p;
}
else if (S[i] == ']' )
--count;
if (count < 0)
{
sum += pos[p] - i;
let temp = S[i];
S[i] = S[pos[p]];
S[pos[p]] = temp;
++p;
count = 1;
}
}
return sum;
}
let s = "[]][][" ;
document.write(swapCount(s) + "<br/>" );
s = "[[][]]" ;
document.write(swapCount(s));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Another Method:
We can do without having to store the positions of ‘[‘.
Below is the implementation :
C++
#include <bits/stdc++.h>
using namespace std;
long swapCount(string chars)
{
int countLeft = 0, countRight = 0;
int swap = 0 , imbalance = 0;
for ( int i = 0; i < chars.length(); i++)
{
if (chars[i] == '[' )
{
countLeft++;
if (imbalance > 0)
{
swap += imbalance;
imbalance--;
}
}
else if (chars[i] == ']' )
{
countRight++;
imbalance = (countRight - countLeft);
}
}
return swap;
}
int main()
{
string s = "[]][][" ;
cout << swapCount(s) << endl;
s = "[[][]]" ;
cout << swapCount(s) << endl;
return 0;
}
|
Java
public class BalanceParan
{
static long swapCount(String s)
{
char [] chars = s.toCharArray();
int countLeft = 0 , countRight = 0 ;
int swap = 0 , imbalance = 0 ;
for ( int i = 0 ; i< chars.length; i++)
{
if (chars[i] == '[' )
{
countLeft++;
if (imbalance > 0 )
{
swap += imbalance;
imbalance--;
}
} else if (chars[i] == ']' )
{
countRight++;
imbalance = (countRight-countLeft);
}
}
return swap;
}
public static void main(String args[])
{
String s = "[]][][" ;
System.out.println(swapCount(s) );
s = "[[][]]" ;
System.out.println(swapCount(s) );
}
}
|
Python3
def swapCount(s):
swap = 0
imbalance = 0 ;
for i in s:
if i = = '[' :
imbalance - = 1
else :
imbalance + = 1
if imbalance > 0 :
swap + = imbalance
return swap
s = "[]][][" ;
print (swapCount(s))
s = "[[][]]" ;
print (swapCount(s))
|
C#
using System;
class GFG
{
public static long swapCount( string s)
{
char [] chars = s.ToCharArray();
int countLeft = 0, countRight = 0;
int swap = 0, imbalance = 0;
for ( int i = 0; i < chars.Length; i++)
{
if (chars[i] == '[' )
{
countLeft++;
if (imbalance > 0)
{
swap += imbalance;
imbalance--;
}
}
else if (chars[i] == ']' )
{
countRight++;
imbalance = (countRight - countLeft);
}
}
return swap;
}
public static void Main( string [] args)
{
string s = "[]][][" ;
Console.WriteLine(swapCount(s));
s = "[[][]]" ;
Console.WriteLine(swapCount(s));
}
}
|
Javascript
<script>
function swapCount(s)
{
let chars = s.split( '' );
let countLeft = 0, countRight = 0;
let swap = 0, imbalance = 0;
for (let i = 0; i < chars.length; i++)
{
if (chars[i] == '[' )
{
countLeft++;
if (imbalance > 0)
{
swap += imbalance;
imbalance--;
}
}
else if (chars[i] == ']' )
{
countRight++;
imbalance = (countRight - countLeft);
}
}
return swap;
}
let s = "[]][][" ;
document.write(swapCount(s) + "</br>" );
s = "[[][]]" ;
document.write(swapCount(s));
</script>
|
Time Complexity :O(N)
Auxiliary Space : O(1)
Last Updated :
09 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...