给定长度为n (n为3的倍数)的字符串str ,其中仅包含集合{0,1,2}中的字符。任务是更新字符串,以使每个字符在最少操作数下具有相同的频率。在一个单一的操作中,字符串的任何字符可以与任何其他字符(也来自同一组)来代替。如果可能有多个字符串打印按字典顺序最小的字符串。
例子:
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.
方法:可以使用贪婪方法解决此问题。每种类型只需要n / 3个字符,其中n是字符串的大小。遍历字符串并计算每种类型的字符数。再次,遍历字符串,然后检查当前字符的计数是否等于n / 3,则无需对当前字符执行任何操作。
但是,如果count(currentChar)!= n / 3,则我们可能需要根据字符的值执行替换操作,以使其保持最小的字典顺序,如下所示:
- 如果当前字符为零(0),并且我们已经处理了所需的零个数,那么如果count [1] <(n / 3)则需要用one(1)替换,如果满足则要用2(1)替换此字符。 count [2] <(n / 3) 。
- 如果当前字符是one(1),那么如果count [0] <(n / 3)则可以将其替换为零(0),如果count [2] <(n / 3)则可以将其替换为二(2 )并我们已经处理了所需的数量,以保持最低的字典顺序
- 如果当前字符为two(2),那么如果count [0] <(n / 3 ),我们可以将其替换为零(0);如果count [2] <(n / 3 ),则可以将其替换为two(2 ) 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function that returns the modified lexicographically
// smallest string after performing minimum number
// of given operations
string formStringMinOperations(string s)
{
// Stores the initial frequencies of characters
// 0s, 1s and 2s
int count[3] = { 0 };
for (auto& c : s)
count++;
// Stores number of processed characters upto that
// point of each type
int processed[3] = { 0 };
// Required number of characters of each type
int reqd = (int)s.size() / 3;
for (int i = 0; i < s.size(); i++) {
// If the current type has already reqd
// number of characters, no need to perform
// any operation
if (count[s[i] - '0'] == reqd)
continue;
// Process all 3 cases
if (s[i] == '0' && count[0] > reqd &&
processed[0] >= reqd) {
// Check for 1 first
if (count[1] < reqd) {
s[i] = '1';
count[1]++;
count[0]--;
}
// Else 2
else if (count[2] < reqd) {
s[i] = '2';
count[2]++;
count[0]--;
}
}
// Here we need to check processed[1] only
// for 2 since 0 is less than 1 and we can
// replace it anytime
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]--;
}
}
// Here we can replace 2 with 0 and 1 anytime
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]--;
}
}
// keep count of processed characters of each
// type
processed[s[i] - '0']++;
}
return s;
}
// Driver Code
int main()
{
string s = "011200";
cout << formStringMinOperations(s);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function that returns the
// modified lexicographically
// smallest String after
// performing minimum number
// of given operations
static String formStringMinOperations(char[] s)
{
// Stores the initial frequencies
// of characters 0s, 1s and 2s
int count[] = new int[3];
for (char c : s)
{
count[(int)c - 48] += 1;
}
// Stores number of processed characters
// upto that point of each type
int processed[] = new int[3];
// Required number of characters of each type
int reqd = (int) s.length / 3;
for (int i = 0; i < s.length; i++)
{
// If the current type has already
// reqd number of characters, no
// need to perform any operation
if (count[s[i] - '0'] == reqd)
{
continue;
}
// Process all 3 cases
if (s[i] == '0' && count[0] > reqd
&& processed[0] >= reqd)
{
// Check for 1 first
if (count[1] < reqd)
{
s[i] = '1';
count[1]++;
count[0]--;
}
// Else 2
else if (count[2] < reqd)
{
s[i] = '2';
count[2]++;
count[0]--;
}
}
// Here we need to check processed[1] only
// for 2 since 0 is less than 1 and we can
// replace it anytime
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]--;
}
}
// Here we can replace 2 with 0 and 1 anytime
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]--;
}
}
// keep count of processed
// characters of each type
processed[s[i] - '0']++;
}
return String.valueOf(s);
}
// Driver Code
public static void main(String[] args)
{
String s = "011200";
System.out.println(formStringMinOperations(s.toCharArray()));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
import math
# Function that returns the modified
# lexicographically smallest string after
# performing minimum number of given operations
def formStringMinOperations(ss):
# Stores the initial frequencies of
# characters 0s, 1s and 2s
count = [0] * 3;
s = list(ss);
for i in range(len(s)):
count[ord(s[i]) - ord('0')] += 1;
# Stores number of processed characters
# upto that point of each type
processed = [0] * 3;
# Required number of characters of each type
reqd = math.floor(len(s) / 3);
for i in range(len(s)):
# If the current type has already reqd
# number of characters, no need to
# perform any operation
if (count[ord(s[i]) - ord('0')] == reqd):
continue;
# Process all 3 cases
if (s[i] == '0' and count[0] > reqd and
processed[0] >= reqd):
# Check for 1 first
if (count[1] < reqd):
s[i] = '1';
count[1] += 1;
count[0] -= 1;
# Else 2
elif (count[2] < reqd):
s[i] = '2';
count[2] += 1;
count[0] -= 1;
# Here we need to check processed[1] only
# for 2 since 0 is less than 1 and we can
# replace it anytime
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;
# Here we can replace 2 with 0 and 1 anytime
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;
# keep count of processed characters
# of each type
processed[ord(s[i]) - ord('0')] += 1;
return ''.join(s);
# Driver Code
s = "011200";
print(formStringMinOperations(s));
# This code is contributed by mits
C#
// C# implementation of the approach
using System;
class GFG
{
// Function that returns the
// modified lexicographically
// smallest String after
// performing minimum number
// of given operations
static String formStringMinOperations(char[] s)
{
// Stores the initial frequencies
// of characters 0s, 1s and 2s
int []count = new int[3];
foreach (char c in s)
{
count[(int)c - 48] += 1;
}
// Stores number of processed characters
// upto that point of each type
int []processed = new int[3];
// Required number of characters of each type
int reqd = (int) s.Length / 3;
for (int i = 0; i < s.Length; i++)
{
// If the current type has already
// reqd number of characters, no
// need to perform any operation
if (count[s[i] - '0'] == reqd)
{
continue;
}
// Process all 3 cases
if (s[i] == '0' && count[0] > reqd
&& processed[0] >= reqd)
{
// Check for 1 first
if (count[1] < reqd)
{
s[i] = '1';
count[1]++;
count[0]--;
}
// Else 2
else if (count[2] < reqd)
{
s[i] = '2';
count[2]++;
count[0]--;
}
}
// Here we need to check processed[1] only
// for 2 since 0 is less than 1 and we can
// replace it anytime
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]--;
}
}
// Here we can replace 2 with 0 and 1 anytime
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]--;
}
}
// keep count of processed
// characters of each type
processed[s[i] - '0']++;
}
return String.Join("",s);
}
// Driver Code
public static void Main(String[] args)
{
String s = "011200";
Console.WriteLine(formStringMinOperations(s.ToCharArray()));
}
}
// This code is contributed by Rajput-Ji
PHP
$reqd &&
$processed[0] >= $reqd)
{
// Check for 1 first
if ($count[1] < $reqd)
{
$s[$i] = '1';
$count[1]++;
$count[0]--;
}
// Else 2
else if ($count[2] < $reqd)
{
$s[$i] = '2';
$count[2]++;
$count[0]--;
}
}
// Here we need to check processed[1] only
// for 2 since 0 is less than 1 and we can
// replace it anytime
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]--;
}
}
// Here we can replace 2 with 0 and 1 anytime
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]--;
}
}
// keep count of processed characters
// of each type
$processed[$s[$i] - '0']++;
}
return $s;
}
// Driver Code
$s = "011200";
echo formStringMinOperations($s);
// This code is contributed by Ryuga
?>
011202