Given a binary string s of length N, the task is to find the lexicographically smallest string using infinite number of swaps between 0’s and 1’s.
Examples:
Input: s = “1001001”
Output: 0000111
Explanation: Lexicographically smallest string of 1001001 is only 0000111
Input: s = “0001”
Output: 0001
Explanation: Lexicographically smallest string of 0001 is only 0001
Input: s = “1”
Output: 1
Explanation: Lexicographically smallest string of 1 is only 1
Naive Approach: The most basic approach to solve this problem is based on below idea:
Since we are allowed to do infinite swaps between 0s and 1s. Therefore while swapping, we will get one such combination where all 0s will come before all 1s.
As by definition, lexicographically smallest binary string must have all 0s before all 1s, therefore, the above such combination will yield the required output.
Now inorder to find such a combination, we can do swapping of 0s and 1s one by one, till we get the required combination where all 0s are before all 1s.
Time Complexity: O(N!), to find all such combinations of given binary string
Auxiliary Space: O(1)
Approach 2: The above approach can be optimised by avoiding the need to find all combinations, based on following observation:
Since we need to find a combination where all 0s come before all 1s, we can sort the given binary string instead, to get the required lexicographically smallest binary string.
Implementation:-
C++
#include <bits/stdc++.h>
using namespace std;
string lexSmallestBinaryString(string s)
{
sort(s.begin(),s.end());
return s;
}
int main()
{
string s = "1111000011" ;
cout << lexSmallestBinaryString(s);
return 0;
}
|
Java
import java.util.Arrays;
public class Main {
public static String lexSmallestBinaryString(String s) {
char [] charArray = s.toCharArray();
Arrays.sort(charArray);
return new String(charArray);
}
public static void main(String[] args) {
String s = "1111000011" ;
System.out.println(lexSmallestBinaryString(s));
}
}
|
Python3
def lexSmallestBinaryString( s):
res = ''.join( sorted (s))
return res;
s = "1111000011" ;
print (lexSmallestBinaryString(s));
|
C#
using System;
public class GFG {
public static string LexSmallestBinaryString( string s)
{
char [] charArray = s.ToCharArray();
Array.Sort(charArray);
return new string (charArray);
}
static public void Main()
{
string s = "1111000011" ;
Console.WriteLine(LexSmallestBinaryString(s));
}
}
|
Javascript
function lexSmallestBinaryString(s)
{
let res = s.split( '' ).sort().join( '' );
return res;
}
let s = "1111000011" ;
console.log(lexSmallestBinaryString(s));
|
Time Complexity: O(N*log(N))
Auxiliary Space: O(1)
Efficient approach: The above approach can be further optimised by avoiding the need to sort the given binary string altogether, as per below idea:
Instead of sorting given binary string, we can simply find the count of set and unset bits (0s and 1s) and form a new binary with the same count where all 0s come before all 1s.
Based on the above idea, follow the steps below to implement this approach:
- Count the number of 0s and 1s in given binary string.
- Create a new empty string
- Insert 0s in the empty string equal to the count of 0s in original string.
- Then append 1s in the new string equal to the count of 1s in original string.
- Return the new string as the lexicographically smallest binary string.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int countOfXs(string s, char x)
{
int n = s.length();
int no_of_x = 0;
for ( int i = 0; i < n; i++) {
if (s[i] == x)
no_of_x++;
}
return no_of_x;
}
string lexSmallestBinaryString(string s)
{
int no_of_0 = countOfXs(s, '0' );
int no_of_1 = countOfXs(s, '1' );
s = "" ;
for ( int i = 0; i < no_of_0; i++) {
s += '0' ;
}
for ( int i = 0; i < no_of_1; i++) {
s += '1' ;
}
return s;
}
int main()
{
string s = "1111000011" ;
cout << lexSmallestBinaryString(s);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int countOfXs(String s, char x)
{
int n = s.length();
int no_of_x = 0 ;
for ( int i = 0 ; i < n; i++)
{
if (s.charAt(i) == x)
no_of_x++;
}
return no_of_x;
}
static String lexSmallestBinaryString(String s)
{
int no_of_0 = countOfXs(s, '0' );
int no_of_1 = countOfXs(s, '1' );
s = "" ;
for ( int i = 0 ; i < no_of_0; i++)
{
s += '0' ;
}
for ( int i = 0 ; i < no_of_1; i++)
{
s += '1' ;
}
return s;
}
public static void main(String[] args)
{
String s = "1111000011" ;
System.out.println(lexSmallestBinaryString(s));
}
}
|
Python3
def countOfXs(s, x):
n = len (s)
no_of_x = 0
for i in range (n):
if s[i] = = x:
no_of_x + = 1
return no_of_x
def lexSmallestBinaryString(s):
no_of_0 = countOfXs(s, '0' )
no_of_1 = countOfXs(s, "1" )
s = ""
for i in range (no_of_0):
s + = "0"
for i in range (no_of_1):
s + = "1"
return s
s = "1111000011"
print (lexSmallestBinaryString(s))
|
C#
using System;
class GFG {
static int countOfXs( string s, char x)
{
int n = s.Length;
int no_of_x = 0;
for ( int i = 0; i < n; i++) {
if (s[i] == x)
no_of_x++;
}
return no_of_x;
}
static string lexSmallestBinaryString( string s)
{
int no_of_0 = countOfXs(s, '0' );
int no_of_1 = countOfXs(s, '1' );
s = "" ;
for ( int i = 0; i < no_of_0; i++) {
s += '0' ;
}
for ( int i = 0; i < no_of_1; i++) {
s += '1' ;
}
return s;
}
public static void Main()
{
string s = "1111000011" ;
Console.Write(lexSmallestBinaryString(s));
}
}
|
Javascript
<script>
function countOfXs(s, x) {
let n = s.length;
let no_of_x = 0;
for (let i = 0; i < n; i++)
{
if (s[i] == x)
no_of_x++;
}
return no_of_x;
}
function lexSmallestBinaryString(s) {
let no_of_0 = countOfXs(s, '0 ');
let no_of_1 = countOfXs(s, ' 1 ');
// Create new string to store
// the required string
s = "";
// Put all 0' s first in resultant string
for (let i = 0; i < no_of_0; i++) {
s += '0' ;
}
for (let i = 0; i < no_of_1; i++)
{
s += '1';
}
return s;
}
let s = "1111000011" ;
document.write(lexSmallestBinaryString(s));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)