给定长度为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),我们已经处理的所需数量的零的,则该字符需要与任一(1)被取代,如果计数[1] <(N / 3)或具有两个(1)如果计数[2] < (n / 3) 。
- 如果当前字符是 one(1),那么我们可以在count[0] < (n / 3)或 two(2) if count[2] < (n / 3)和我们已经处理了维持最低字典顺序所需的数量
- 如果当前字符是 two(2),那么如果count[0] < (n / 3)或者用 two(2) if count[2] < (n / 3) ,我们可以用零 (0) 替换它。
下面是上述方法的实现:
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
?>
Javascript
011202
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。