📌  相关文章
📜  使所有字符的频率等于K的最小操作

📅  最后修改于: 2021-04-22 08:01:51             🧑  作者: Mango

给定长度为N的字符串S。任务是查找字符串所需的最小步数,以使其具有K个完全相同的频率的完全不同的K个字母。

注意:第一步,我们可以将一个字母更改为任何其他字母。

例子:

Input: S = "abbc", N = 4, K = 2
Output: 1 
In one step convert 'c' to 'a'. Hence string has 
two different letters a and b both 
occurring 2 times. 

方法

  1. 检查K是否除以N,则只能转换给定的字符串,否则不能转换。
  2. 维护数组A中存在于字符串S中的所有字母的计数。
  3. 评估E = N / K ,即最终字符串出现字母的频率。
  4. 将频率大于或等于E且小于E的字母分成两部分。
  5. 保持每个字母将其计数转换为E所需的步数,对在上述步骤中获得的这些向量进行排序。
  6. 最后,请尽可能选择:
    Set 1 : 0   Set 2 : K
    Set 1 : 1   Set 2 : K-1 .... so on
    
  7. 保留ans变量以计算步骤6中所有可能性中的最小步骤数。
  8. 假设L1是Set 1所需的操作数,L2是Set 2所需的操作数。则所需的总操作数为L1,L2的最大值。因为假设’a’少了一个字符串,而’b’少了一个字符串,所以我们可以将’a’更改为’b’,从而减少了步数。

下面是上述方法的实现:

C++
// C++ program to convert the given string
  
#include 
using namespace std;
  
// Function to find the minimum number of
// operations to convert the given string
void minOperation(string S, int N, int K)
{
    // Check if N is divisible by K
    if (N % K) {
        cout << "Not Possible" << endl;
        return;
    }
  
    // Array to store frequency of characters
    // in given string
    int count[26] = { 0 };
    for (int i = 0; i < N; i++) {
        count[S[i] - 97]++;
    }
  
    int E = N / K;
  
    vector greaterE;
    vector lessE;
  
    for (int i = 0; i < 26; i++) {
  
        // Two arrays with number of operations
        // required
        if (count[i] < E)
            lessE.push_back(E - count[i]);
        else
            greaterE.push_back(count[i] - E);
    }
  
    sort(greaterE.begin(), greaterE.end());
    sort(lessE.begin(), lessE.end());
  
    int mi = INT_MAX;
  
    for (int i = 0; i <= K; i++) {
  
        // Checking for all possibility
        int set1 = i;
        int set2 = K - i;
  
        if (greaterE.size() >= set1 && lessE.size() >= set2) {
  
            int step1 = 0;
            int step2 = 0;
  
            for (int j = 0; j < set1; j++)
                step1 += greaterE[j];
  
            for (int j = 0; j < set2; j++)
                step2 += lessE[j];
  
            mi = min(mi, max(step1, step2));
        }
    }
  
    cout << mi << endl;
}
  
// Driver Code
int main()
{
    string S = "accb";
    int N = S.size();
    int K = 2;
  
    minOperation(S, N, K);
  
    return 0;
}


Java
// JAVA program to convert the given string
import java.util.*;
  
class GFG
{
      
    // Function to find the minimum number of
    // operations to convert the given string
    static void minOperation(String S, int N, int K)
    {
        // Check if N is divisible by K
        if (N % K != 0)
        {
            System.out.println("Not Possible");
        }
        else
        {
            // Array to store frequency of characters
            // in given string
            int [] count = new int[26];
              
            for (int i = 0; i < N; i++)
            {
                count[(S.charAt(i) - 97)]++;
            }
          
            int E = N / K;
          
            Vector greaterE = new Vector<>(); 
            Vector lessE = new Vector<>(); 
          
            for (int i = 0; i < 26; i++) 
            {
          
                // Two arrays with number of operations
                // required
                if (count[i] < E)
                    lessE.add(E - count[i]);
                else
                    greaterE.add(count[i] - E);
            }
          
            Collections.sort(greaterE);
            Collections.sort(lessE);
          
            int mi = Integer.MAX_VALUE;
          
            for (int i = 0; i <= K; i++)
            {
          
                // Checking for all possibility
                int set1 = i;
                int set2 = K - i;
          
                if (greaterE.size() >= set1 && 
                            lessE.size() >= set2) 
                {
          
                    int step1 = 0;
                    int step2 = 0;
          
                    for (int j = 0; j < set1; j++)
                        step1 += greaterE.get(j);
          
                    for (int j = 0; j < set2; j++)
                        step2 += lessE.get(j);
          
                    mi = Math.min(mi, Math.max(step1, step2));
                }
            }
          
            System.out.println(mi);
        }
  
    }
      
    // Driver Code
    public static void main (String[] args) 
    {
        String S = "accb";
        int N = S.length();
        int K = 2;
      
        minOperation(S, N, K);
    }
}
  
// This code is contributed by ihritik


Python3
# Python3 program to convert the given string 
  
# Function to find the minimum number of 
# operations to convert the given string 
def minOperation(S, N, K): 
  
    # Check if N is divisible by K 
    if N % K: 
        print("Not Possible") 
        return
  
    # Array to store frequency of 
    # characters in given string 
    count = [0] * 26
    for i in range(0, N): 
        count[ord(S[i]) - 97] += 1
  
    E = N // K 
    greaterE = []
    lessE = []
  
    for i in range(0, 26): 
  
        # Two arrays with number of 
        # operations required 
        if count[i] < E:
            lessE.append(E - count[i]) 
        else:
            greaterE.append(count[i] - E) 
  
    greaterE.sort() 
    lessE.sort() 
  
    mi = float('inf') 
    for i in range(0, K + 1): 
  
        # Checking for all possibility 
        set1, set2 = i, K - i 
  
        if (len(greaterE) >= set1 and 
            len(lessE) >= set2): 
  
            step1, step2 = 0, 0
  
            for j in range(0, set1): 
                step1 += greaterE[j] 
  
            for j in range(0, set2): 
                step2 += lessE[j] 
  
            mi = min(mi, max(step1, step2))
  
    print(mi) 
  
# Driver Code 
if __name__ == "__main__":
  
    S = "accb"
    N = len(S) 
    K = 2
  
    minOperation(S, N, K) 
      
# This code is contributed by Rituraj Jain


C#
// C# program to convert the given string
using System;
using System.Collections.Generic;
  
class GFG
{
      
    // Function to find the minimum number of
    // operations to convert the given string
    static void minOperation(string S, int N, int K)
    {
        // Check if N is divisible by K
        if (N % K != 0) 
        {
            Console.WriteLine("Not Possible");
        }
        else
        {
            // Array to store frequency of characters
            // in given string
            int [] count = new int[26];
              
            for (int i = 0; i < N; i++) 
            {
                count[(S[i] - 97)]++;
            }
          
            int E = N / K;
          
            List greaterE = new List();
            List lessE = new List();
              
            for (int i = 0; i < 26; i++) 
            {
          
                // Two arrays with number of operations
                // required
                if (count[i] < E)
                    lessE.Add(E - count[i]);
                else
                    greaterE.Add(count[i] - E);
            }
          
            greaterE.Sort();
            lessE.Sort();
          
            int mi = Int32.MaxValue;
          
            for (int i = 0; i <= K; i++) 
            {
          
                // Checking for all possibility
                int set1 = i;
                int set2 = K - i;
          
                if (greaterE.Count >= set1 && 
                            lessE.Count >= set2) 
                {
          
                    int step1 = 0;
                    int step2 = 0;
          
                    for (int j = 0; j < set1; j++)
                        step1 += greaterE[j];
          
                    for (int j = 0; j < set2; j++)
                        step2 += lessE[j];
          
                    mi = Math.Min(mi, Math.Max(step1, step2));
                }
            }
          
            Console.WriteLine(mi);
        }
  
    }
      
    // Driver Code
    public static void Main () 
    {
        string S = "accb";
        int N = S.Length;
        int K = 2;
      
        minOperation(S, N, K);
    }
}
  
// This code is contributed by ihritik


输出:
1