Form lexicographically smallest string with minimum replacements having equal number of 0s, 1s and 2s
Last Updated :
15 Sep, 2022
Given string str of length n (n is a multiple of 3) containing characters only from the set {0, 1, 2}. The task is to update the string such that each character has the same frequency with a minimum number of operations. In a single operation, any character of the string can be replaced with any other character (also from the same set). If there are multiple strings possible then print the lexicographically smallest one.
Examples:
Input: str = “000000”
Output: 001122
Replace 3rd and 4th ‘0’ with ‘1’ and 5th and 6th ‘0’ with ‘2’ such that given condition is satisfied and it forms lexicographically smallest string
Input: str = “211200”
Output: 211200
The string already has equal number of 0s, 1s and 2s, hence there is no need to perform any operation.
Approach: This problem can be solved using a greedy approach. We need only n / 3 number of characters of each type where n is the size of the string. Iterate over the string and count the number of characters of each type. Again, iterate over the string and now check if the current character’s count is equal to n / 3 then there is no need to perform any operation on the current character.
However, if count(currentChar) != n / 3 then we may need to perform a replacement operation depending on the value of the character in such a way that it maintains the smallest lexicographical order as follows:
- If the current character is zero(0) and we have already processed required number of zeroes, then this character needs to be replaced with either one(1) if count[1] < (n / 3) or with two(1) if count[2] < (n / 3).
- If the current character is one(1), then we can either replace it with zero(0) if count[0] < (n / 3) or with two(2) if count[2] < (n / 3) and we have already processed required number of ones to maintain lowest lexicographical order
- If the current character is two(2), then we can either replace it with zero(0) if count[0] < (n / 3) or with two(2) if count[2] < (n / 3).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
string formStringMinOperations(string s)
{
int count[3] = { 0 };
for ( auto & c : s)
count++;
int processed[3] = { 0 };
int reqd = ( int )s.size() / 3;
for ( int i = 0; i < s.size(); i++) {
if (count[s[i] - '0' ] == reqd)
continue ;
if (s[i] == '0' && count[0] > reqd &&
processed[0] >= reqd) {
if (count[1] < reqd) {
s[i] = '1' ;
count[1]++;
count[0]--;
}
else if (count[2] < reqd) {
s[i] = '2' ;
count[2]++;
count[0]--;
}
}
if (s[i] == '1' && count[1] > reqd) {
if (count[0] < reqd) {
s[i] = '0' ;
count[0]++;
count[1]--;
}
else if (count[2] < reqd &&
processed[1] >= reqd) {
s[i] = '2' ;
count[2]++;
count[1]--;
}
}
if (s[i] == '2' && count[2] > reqd) {
if (count[0] < reqd) {
s[i] = '0' ;
count[0]++;
count[2]--;
}
else if (count[1] < reqd) {
s[i] = '1' ;
count[1]++;
count[2]--;
}
}
processed[s[i] - '0' ]++;
}
return s;
}
int main()
{
string s = "011200" ;
cout << formStringMinOperations(s);
return 0;
}
|
Java
class GFG
{
static String formStringMinOperations( char [] s)
{
int count[] = new int [ 3 ];
for ( char c : s)
{
count[( int )c - 48 ] += 1 ;
}
int processed[] = new int [ 3 ];
int reqd = ( int ) s.length / 3 ;
for ( int i = 0 ; i < s.length; i++)
{
if (count[s[i] - '0' ] == reqd)
{
continue ;
}
if (s[i] == '0' && count[ 0 ] > reqd
&& processed[ 0 ] >= reqd)
{
if (count[ 1 ] < reqd)
{
s[i] = '1' ;
count[ 1 ]++;
count[ 0 ]--;
}
else if (count[ 2 ] < reqd)
{
s[i] = '2' ;
count[ 2 ]++;
count[ 0 ]--;
}
}
if (s[i] == '1' && count[ 1 ] > reqd)
{
if (count[ 0 ] < reqd)
{
s[i] = '0' ;
count[ 0 ]++;
count[ 1 ]--;
}
else if (count[ 2 ] < reqd
&& processed[ 1 ] >= reqd)
{
s[i] = '2' ;
count[ 2 ]++;
count[ 1 ]--;
}
}
if (s[i] == '2' && count[ 2 ] > reqd)
{
if (count[ 0 ] < reqd)
{
s[i] = '0' ;
count[ 0 ]++;
count[ 2 ]--;
}
else if (count[ 1 ] < reqd)
{
s[i] = '1' ;
count[ 1 ]++;
count[ 2 ]--;
}
}
processed[s[i] - '0' ]++;
}
return String.valueOf(s);
}
public static void main(String[] args)
{
String s = "011200" ;
System.out.println(formStringMinOperations(s.toCharArray()));
}
}
|
Python3
import math
def formStringMinOperations(ss):
count = [ 0 ] * 3 ;
s = list (ss);
for i in range ( len (s)):
count[ ord (s[i]) - ord ( '0' )] + = 1 ;
processed = [ 0 ] * 3 ;
reqd = math.floor( len (s) / 3 );
for i in range ( len (s)):
if (count[ ord (s[i]) - ord ( '0' )] = = reqd):
continue ;
if (s[i] = = '0' and count[ 0 ] > reqd and
processed[ 0 ] > = reqd):
if (count[ 1 ] < reqd):
s[i] = '1' ;
count[ 1 ] + = 1 ;
count[ 0 ] - = 1 ;
elif (count[ 2 ] < reqd):
s[i] = '2' ;
count[ 2 ] + = 1 ;
count[ 0 ] - = 1 ;
if (s[i] = = '1' and count[ 1 ] > reqd):
if (count[ 0 ] < reqd):
s[i] = '0' ;
count[ 0 ] + = 1 ;
count[ 1 ] - = 1 ;
elif (count[ 2 ] < reqd and
processed[ 1 ] > = reqd):
s[i] = '2' ;
count[ 2 ] + = 1 ;
count[ 1 ] - = 1 ;
if (s[i] = = '2' and count[ 2 ] > reqd):
if (count[ 0 ] < reqd):
s[i] = '0' ;
count[ 0 ] + = 1 ;
count[ 2 ] - = 1 ;
elif (count[ 1 ] < reqd):
s[i] = '1' ;
count[ 1 ] + = 1 ;
count[ 2 ] - = 1 ;
processed[ ord (s[i]) - ord ( '0' )] + = 1 ;
return ''.join(s);
s = "011200" ;
print (formStringMinOperations(s));
|
C#
using System;
class GFG
{
static String formStringMinOperations( char [] s)
{
int []count = new int [3];
foreach ( char c in s)
{
count[( int )c - 48] += 1;
}
int []processed = new int [3];
int reqd = ( int ) s.Length / 3;
for ( int i = 0; i < s.Length; i++)
{
if (count[s[i] - '0' ] == reqd)
{
continue ;
}
if (s[i] == '0' && count[0] > reqd
&& processed[0] >= reqd)
{
if (count[1] < reqd)
{
s[i] = '1' ;
count[1]++;
count[0]--;
}
else if (count[2] < reqd)
{
s[i] = '2' ;
count[2]++;
count[0]--;
}
}
if (s[i] == '1' && count[1] > reqd)
{
if (count[0] < reqd)
{
s[i] = '0' ;
count[0]++;
count[1]--;
}
else if (count[2] < reqd
&& processed[1] >= reqd)
{
s[i] = '2' ;
count[2]++;
count[1]--;
}
}
if (s[i] == '2' && count[2] > reqd)
{
if (count[0] < reqd)
{
s[i] = '0' ;
count[0]++;
count[2]--;
}
else if (count[1] < reqd)
{
s[i] = '1' ;
count[1]++;
count[2]--;
}
}
processed[s[i] - '0' ]++;
}
return String.Join( "" ,s);
}
public static void Main(String[] args)
{
String s = "011200" ;
Console.WriteLine(formStringMinOperations(s.ToCharArray()));
}
}
|
PHP
<?php
function formStringMinOperations( $s )
{
$count = array_fill (0, 3, 0);
for ( $i = 0; $i < strlen ( $s ) ; $i ++)
$count [ $s [ $i ] - '0' ]++;
$processed = array_fill (0, 3, 0);
$reqd = floor ( strlen ( $s ) / 3);
for ( $i = 0; $i < strlen ( $s ); $i ++)
{
if ( $count [ $s [ $i ] - '0' ] == $reqd )
continue ;
if ( $s [ $i ] == '0' && $count [0] > $reqd &&
$processed [0] >= $reqd )
{
if ( $count [1] < $reqd )
{
$s [ $i ] = '1' ;
$count [1]++;
$count [0]--;
}
else if ( $count [2] < $reqd )
{
$s [ $i ] = '2' ;
$count [2]++;
$count [0]--;
}
}
if ( $s [ $i ] == '1' && $count [1] > $reqd )
{
if ( $count [0] < $reqd )
{
$s [ $i ] = '0' ;
$count [0]++;
$count [1]--;
}
else if ( count [2] < $reqd &&
$processed [1] >= $reqd )
{
$s [ $i ] = '2' ;
$count [2]++;
$count [1]--;
}
}
if ( $s [ $i ] == '2' && $count [2] > $reqd )
{
if ( $count [0] < $reqd )
{
$s [ $i ] = '0' ;
$count [0]++;
$count [2]--;
}
else if ( $count [1] < $reqd )
{
$s [ $i ] = '1' ;
$count [1]++;
$count [2]--;
}
}
$processed [ $s [ $i ] - '0' ]++;
}
return $s ;
}
$s = "011200" ;
echo formStringMinOperations( $s );
?>
|
Javascript
<script>
function formStringMinOperations(s)
{
var count = new Array(3).fill(0);
for (const c of s) {
count += 1;
}
var processed = new Array(3).fill(0);
var reqd = parseInt(s.length / 3);
for ( var i = 0; i < s.length; i++) {
if (count[s[i].charCodeAt(0) -
"0" .charCodeAt(0)] === reqd) {
continue ;
}
if (s[i] === "0" && count[0] >
reqd && processed[0] >= reqd) {
if (count[1] < reqd) {
s[i] = "1" ;
count[1]++;
count[0]--;
}
else if (count[2] < reqd) {
s[i] = "2" ;
count[2]++;
count[0]--;
}
}
if (s[i] === "1" && count[1] > reqd) {
if (count[0] < reqd) {
s[i] = "0" ;
count[0]++;
count[1]--;
} else if (count[2] < reqd &&
processed[1] >= reqd) {
s[i] = "2" ;
count[2]++;
count[1]--;
}
}
if (s[i] === "2" && count[2] > reqd) {
if (count[0] < reqd) {
s[i] = "0" ;
count[0]++;
count[2]--;
} else if (count[1] < reqd) {
s[i] = "1" ;
count[1]++;
count[2]--;
}
}
processed[s[i].charCodeAt(0) -
"0" .charCodeAt(0)]++;
}
return s.join( "" );
}
var s = "011200" ;
document.write(formStringMinOperations(s.split( "" )));
</script>
|
Complexity Analysis:
- Time Complexity: O(n), where n is the size of the given string
- Auxiliary Space: O(1), as 3 is termed as constant.
Share your thoughts in the comments
Please Login to comment...