📌  相关文章
📜  使用具有相同数量的 0、1 和 2 的最少替换来形成字典序最小的字符串

📅  最后修改于: 2021-10-25 09:15:11             🧑  作者: Mango

给定长度为n (n 是 3 的倍数)的字符串str仅包含来自集合{0, 1, 2} 的字符。任务是更新字符串,使每个字符的频率相同,操作次数最少。在单个操作中,字符串的任何字符都可以替换为任何其他字符(也来自同一组)。如果可能有多个字符串,则打印字典序最小的字符串。
例子:

方法:这个问题可以使用贪心方法来解决。我们只需要每种类型的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 现场工作专业课程学生竞争性编程现场课程