给定一个长度为N的字符串S和一个整数K ,任务是找到使字符串回文和 K 周期所需的最少字符替换。
例子:
Input: S = “abaaba”, K = 2
Output: 2
Explanation: The optimal way is to transform the string to “aaaaaa”. Therefore, the minimum number of changes required is 2.
Input: S = “aabbcbbcb”, K = 3
Output: 2
Explanation:
The optimal way is to transform the string to ”bcbbcbbcb”. Therefore, the minimum number of changes required is 2.
方法:为了尽量减少需要在字符串进行的更改次数,请观察转换后的字符串的以下性质,即回文和 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来存储每个字符的频率。
- 使用变量j以K为间隔迭代从i开始的字符串的字符,并存储每个字符的频率。
- 反向迭代字符串,从(N – i – 1) 开始,使用变量j以K为间隔,并存储每个字符的频率。如果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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live