📌  相关文章
📜  形成字典上最小的字符串,并具有等于0、1、2和2的最小替换数

📅  最后修改于: 2021-04-24 15:21:36             🧑  作者: Mango

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

例子:

方法:可以使用贪婪方法解决此问题。每种类型只需要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