📌  相关文章
📜  获得 K 周期回文字符串所需的最少替换次数

📅  最后修改于: 2021-10-27 08:43:15             🧑  作者: Mango

给定一个长度为N的字符串S和一个整数K ,任务是找到使字符串回文和 K 周期所需的最少字符替换。

例子:

方法:为了尽量减少需要在字符串进行的更改次数,请观察转换后的字符串的以下性质,即回文和 K 周期:

  • 一个K 周期字符串只能通过连接几个长度为K 的回文字符串来构成。
  • 位置 i, K – i – 1, i + K, 2K – i – 1, i + 2K, 3K – i – 1, i + 3K, … 的所有字符对于所有0 ≤ i < K ,都是相等的。

问题简化为使所有字符等于在给定字符串中这些位置出现最多次数的字符。请按照以下步骤解决上述问题:

  • 使用0初始化变量ans ,该变量存储满足给定条件所需的最小更改。
  • 使用变量i在范围[0, K / 2] 上迭代
    • 创建一个 hashmap, mp来存储每个字符的频率。
    • 使用变量jK为间隔迭代从i开始的字符串的字符,并存储每个字符的频率。
    • 反向迭代字符串,从(N – i – 1) 开始,使用变量jK为间隔,并存储每个字符的频率。如果K是奇数且i = K / 2 ,则跳出循环。
    • 在访问过的字符中找到一个字符的最大频率并将其存储在一个变量中,比如curr_max
    • 在上述步骤之后,如果K为奇数且i = K/2 ,则将ans增加(N/K – curr_max)否则,将ans增加(N/K – 2*curr_max)。
  • 经过以上步骤,打印ans的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum number
// of changes to make the string K-
// periodic and palindrome
int findMinimumChanges(int N, int K,
                       string S)
{
 
    // Initialize ans with 0
    int ans = 0;
 
    // Iterate from 0 to (K+1) / 2
    for (int i = 0; i < (K + 1) / 2; i++) {
 
        // Store frequency of character
        map mp;
 
        // Iterate through all indices,
        // i, i+K, i+2k.... and store
        // the frequency of character
        for (int j = i; j < N; j += K) {
 
            // Increase the frequency
            // of current character
            mp[S[j]]++;
        }
 
        // Iterate through all indices
        // K-i, 2K-i, 3K-i.... and store
        // the frequency of  character
        for (int j = N - i - 1;
             j >= 0; j -= K) {
 
            // If K is odd & i is samw
            // as K/2, break the loop
            if (K & 1 and i == K / 2)
                break;
 
            // Increase the frequency
            // of current character
            mp[S[j]]++;
        }
 
        // Find the maximum frequency
        // of a character among all
        // visited characters
        int curr_max = INT_MIN;
        for (auto p : mp)
            curr_max = max(curr_max,
                           p.second);
 
        // If K is odd and i is same
        // as K/2 then, only N/K
        // characters is visited
        if (K & 1 and i == K / 2)
            ans += (N / K - curr_max);
 
        // Otherwise N/K * 2 characters
        // has visited
        else
            ans += (N / K * 2 - curr_max);
    }
 
    // Return the result
    return ans;
}
 
// Driver Code
int main()
{
    string S = "aabbcbbcb";
    int N = S.length();
    int K = 3;
 
    // Function Call
    cout << findMinimumChanges(N, K, S);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to find the minimum number
// of changes to make the String K-
// periodic and palindrome
static int findMinimumChanges(int N, int K,
                              char[] S)
{
     
    // Initialize ans with 0
    int ans = 0;
 
    // Iterate from 0 to (K+1) / 2
    for(int i = 0; i < (K + 1) / 2; i++)
    {
         
        // Store frequency of character
        HashMap mp = new HashMap<>();
 
        // Iterate through all indices,
        // i, i+K, i+2k.... and store
        // the frequency of character
        for(int j = i; j < N; j += K)
        {
             
            // Increase the frequency
            // of current character
            if (mp.containsKey(S[j]))
            {
                mp.put(S[j], mp.get(S[j]) + 1);
            }
            else
            {
                mp.put(S[j], 1);
            }
        }
 
        // Iterate through all indices
        // K-i, 2K-i, 3K-i.... and store
        // the frequency of  character
        for(int j = N - i - 1; j >= 0; j -= K)
        {
             
            // If K is odd & i is samw
            // as K/2, break the loop
            if (K % 2 == 1 && i == K / 2)
                break;
 
            // Increase the frequency
            // of current character
            if (mp.containsKey(S[j]))
            {
                mp.put(S[j], mp.get(S[j]) + 1);
            }
            else
            {
                mp.put(S[j], 1);
            }
        }
 
        // Find the maximum frequency
        // of a character among all
        // visited characters
        int curr_max = Integer.MIN_VALUE;
        for(Map.Entry p : mp.entrySet())
        {
            curr_max = Math.max(curr_max,
                                p.getValue());
        }
 
        // If K is odd and i is same
        // as K/2 then, only N/K
        // characters is visited
        if ((K % 2 == 1) &&  i == K / 2)
            ans += (N / K - curr_max);
 
        // Otherwise N/K * 2 characters
        // has visited
        else
            ans += (N / K * 2 - curr_max);
    }
 
    // Return the result
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    String S = "aabbcbbcb";
    int N = S.length();
    int K = 3;
 
    // Function Call
    System.out.print(findMinimumChanges(
        N, K, S.toCharArray()));
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 program for the
# above approach
 
import sys
# Function to find the minimum
# number of changes to make
# the string K- periodic and
# palindrome
def findMinimumChanges(N, K, S):
   
    # Initialize ans with 0
    ans = 0
 
    # Iterate from 0 to (K+1) / 2
    for i in range((K + 1) // 2):
       
        # Store frequency of
        # character
        mp = {}
 
        # Iterate through all indices,
        # i, i+K, i+2k.... and store
        # the frequency of character
        for j in range(i, N, K):
           
            # Increase the frequency
            # of current character
            mp[S[j]] = mp.get(S[j], 0) + 1
 
        # Iterate through all indices
        # K-i, 2K-i, 3K-i.... and store
        # the frequency of  character
        j = N - i - 1
         
        while(j >= 0):
           
            # If K is odd & i is samw
            # as K/2, break the loop
            if ((K & 1) and
                (i == K // 2)):
                break
 
            # Increase the frequency
            # of current character
            mp[S[j]] = mp.get(S[j], 0) + 1
            j -= K
 
        # Find the maximum frequency
        # of a character among all
        # visited characters
        curr_max = -sys.maxsize - 1
         
        for key, value in mp.items():
            curr_max = max(curr_max,
                           value)
 
        # If K is odd and i is same
        # as K/2 then, only N/K
        # characters is visited
        if ((K & 1) and
            (i == K // 2)):
            ans += (N // K - curr_max)
 
        # Otherwise N/K * 2
        # characters has visited
        else:
            ans += (N // K * 2 -
                    curr_max)
 
    # Return the result
    return ans
 
# Driver Code
if __name__ == '__main__':
   
    S = "aabbcbbcb"
    N = len(S)
    K = 3
 
    # Function Call
    print(findMinimumChanges(N, K, S))
 
# This code is contributed by SURENDRA_GANGWAR


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find the minimum number
// of changes to make the String K-
// periodic and palindrome
static int findMinimumChanges(int N, int K,
                              char[] S)
{
     
    // Initialize ans with 0
    int ans = 0;
 
    // Iterate from 0 to (K+1) / 2
    for(int i = 0; i < (K + 1) / 2; i++)
    {
         
        // Store frequency of character
        Dictionary mp = new Dictionary();
 
        // Iterate through all indices,
        // i, i+K, i+2k.... and store
        // the frequency of character
        for(int j = i; j < N; j += K)
        {
             
            // Increase the frequency
            // of current character
            if (mp.ContainsKey(S[j]))
            {
                mp[S[j]]++;
            }
            else
            {
                mp.Add(S[j], 1);
            }
        }
 
        // Iterate through all indices
        // K-i, 2K-i, 3K-i.... and store
        // the frequency of  character
        for(int j = N - i - 1; j >= 0; j -= K)
        {
             
            // If K is odd & i is samw
            // as K/2, break the loop
            if (K % 2 == 1 && i == K / 2)
                break;
 
            // Increase the frequency
            // of current character
            if (mp.ContainsKey(S[j]))
            {
                mp[S[j]]++;
            }
            else
            {
                mp.Add(S[j], 1);
            }
        }
 
        // Find the maximum frequency
        // of a character among all
        // visited characters
        int curr_max = int.MinValue;
        foreach(KeyValuePair p in mp)
        {
            curr_max = Math.Max(curr_max,
                                p.Value);
        }
 
        // If K is odd and i is same
        // as K/2 then, only N/K
        // characters is visited
        if ((K % 2 == 1) &&  i == K / 2)
            ans += (N / K - curr_max);
 
        // Otherwise N/K * 2 characters
        // has visited
        else
            ans += (N / K * 2 - curr_max);
    }
 
    // Return the result
    return ans;
}
 
// Driver Code
public static void Main(String[] args)
{
    String S = "aabbcbbcb";
    int N = S.Length;
    int K = 3;
 
    // Function Call
    Console.Write(findMinimumChanges(
        N, K, S.ToCharArray()));
}
}
 
// This code is contributed by Amit Katiyar


Javascript


输出:
2

时间复杂度: O(N)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程