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)))
|
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)
This article is contributed by Aarti_Rathi and Aditya Kamath. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.