给定一个长度为N的字符串S和一个由小写字母组成的数组A 。还给出了一个正整数K 。任务是找到使字符串S K周期性所需的最小交换次数(在 S 和 A 之间)。
笔记:
- 如果对于字符串S[i] = S[i+K]中的每个位置 i,则称该字符串是 K 周期的。
- 在一个举动,S只有一个字符可以与A的字符互换
- A 中的字符可以多次使用。
例子:
Input: S = “nihsiakyt”, K = 3, A = [‘n’, ‘i’, ‘p’, ‘s’, ‘q’]
Output: 6
Explanation:
Considering 0 based positioning for the string S:
Positions 3, 6 should be replaced with ‘n’.
Position 7 should be replaced with ‘i’.
Positions 2, 5, 8 can be replaced with any character from A to make the string K periodic.
Final 3 periodic string: “nisnisnis”
Therefore minimum swaps required = 6
Input: S = “abcdeactr”, K = 4, A = [‘a’, ‘c’, ‘p’]
Output: 5
Explanation:
In total 5 changes are needed to make the string 4 periodic.
方法:这个问题可以借助频率计数和哈希来解决。
- 为了解决上面提到的问题,我们使用一个二维数组freq[K][26]来存储所有字符在j % K位置的频率 .
- 使用布尔数组来标记数组 A 中存在的所有字符。
- 对于 0 到 K 范围内的所有字符,将有N / K或(N / K + 1) 个应该相同的字符。
- 所以对于所有这样的字符,我们检查哪个字符在位置 i 的频率最大,并且也出现在数组 A 中。
- 将其添加到答案中,即 .
- 我们还将在答案中加 1,如果
- 因为所有这样的字符i 都会有N / K + 1 个字符。
下面是上述方法的实现:
C++
// C++ code to find the minimum
// number of swaps required to
// make the string K periodic
#include
using namespace std;
int minFlip(string s, int n,
int k, char a[],
int p)
{
bool allowed[26] = { 0 };
for (int i = 0; i < p; i++) {
// Mark all allowed
// characters as true
allowed[a[i] - 'a'] = true;
}
char freq[k][26];
// Initialize the freq array to 0
for (int i = 0; i < k; i++)
for (int j = 0; j < 26; j++)
freq[i][j] = 0;
for (int i = 0; i < n; i++) {
// Increase the frequency
// of each character
freq[i % k][s[i] - 'a'] += 1;
}
int ans = 0;
// Total number of periods of
// size K in the string
int totalpositions = n / k;
for (int i = 0; i < k; i++) {
int maxfrequency = 0;
for (int j = 0; j < 26; j++) {
// Check if the current character
// is present in allowed
// and whether the current
// frequency is greater than
// all previous frequencies
// for this position
if (freq[i][j] > maxfrequency
and allowed[j] == true)
maxfrequency = freq[i][j];
}
// update the answer by
// subtracting the maxfrequency
// from total positions
// if there exist extra character
// at the end of the string
// apart from the n/k characters
// then add 1.
ans
+= (totalpositions
- maxfrequency
+ ((i % k < n % k)
? 1
: 0));
}
cout << ans << endl;
}
// Driver code
int main()
{
string S = "nihsiakyt";
int n = S.length();
int K = 3;
char A[5]
= { 'n', 'i', 'p', 's', 'q' };
int p = sizeof(A) / sizeof(A[0]);
minFlip(S, n, K, A, p);
return 0;
}
Java
// Java code to find the minimum
// number of swaps required to
// make the String K periodic
import java.util.*;
class GFG{
static void minFlip(String s, int n,
int k, char a[],
int p)
{
boolean allowed[] = new boolean[26];
for(int i = 0; i < p; i++)
{
// Mark all allowed
// characters as true
allowed[a[i] - 'a'] = true;
}
char [][]freq = new char[k][26];
// Initialize the freq array to 0
for(int i = 0; i < k; i++)
for(int j = 0; j < 26; j++)
freq[i][j] = 0;
for(int i = 0; i < n; i++)
{
// Increase the frequency
// of each character
freq[i % k][s.charAt(i) - 'a'] += 1;
}
int ans = 0;
// Total number of periods
// of size K in the String
int totalpositions = n / k;
for(int i = 0; i < k; i++)
{
int maxfrequency = 0;
for(int j = 0; j < 26; j++)
{
// Check if the current character
// is present in allowed
// and whether the current
// frequency is greater than
// all previous frequencies
// for this position
if (freq[i][j] > maxfrequency &&
allowed[j] == true)
maxfrequency = freq[i][j];
}
// Update the answer by
// subtracting the maxfrequency
// from total positions
// if there exist extra character
// at the end of the String
// apart from the n/k characters
// then add 1.
ans += (totalpositions -
maxfrequency +
((i % k < n %
k) ? 1 : 0));
}
System.out.print(ans + "\n");
}
// Driver code
public static void main(String[] args)
{
String S = "nihsiakyt";
int n = S.length();
int K = 3;
char []A = { 'n', 'i', 'p', 's', 'q' };
int p = A.length;
minFlip(S, n, K, A, p);
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 code to find the minimum
# number of swaps required to
# make the string K periodic
def minFlip(s, n, k, a, p):
allowed = [0] * 26
for i in range(p):
# Mark all allowed
# characters as true
allowed[ord(a[i]) - ord('a')] = True
freq = [[0 for x in range(26)]
for y in range(k)]
# Initialize the freq array to 0
for i in range(k):
for j in range(26):
freq[i][j] = 0
for i in range(n):
# Increase the frequency
# of each character
freq[i % k][ord(s[i]) - ord('a')] += 1
ans = 0
# Total number of periods of
# size K in the string
totalpositions = n // k
for i in range(k):
maxfrequency = 0
for j in range(26):
# Check if the current character
# is present in allowed
# and whether the current
# frequency is greater than
# all previous frequencies
# for this position
if (freq[i][j] > maxfrequency and
allowed[j] == True):
maxfrequency = freq[i][j]
# Update the answer by
# subtracting the maxfrequency
# from total positions
# if there exist extra character
# at the end of the string
# apart from the n/k characters
# then add 1.
ans += (totalpositions - maxfrequency)
if (i % k < n % k):
ans += 1
print(ans)
# Driver code
if __name__ == "__main__":
S = "nihsiakyt"
n = len(S)
K = 3
A = [ 'n', 'i', 'p', 's', 'q' ]
p = len(A)
minFlip(S, n, K, A, p)
# This code is contributed by chitranayal
C#
// C# code to find the minimum
// number of swaps required to
// make the String K periodic
using System;
class GFG{
static void minFlip(String s, int n,
int k, char []a,
int p)
{
bool []allowed = new bool[26];
for(int i = 0; i < p; i++)
{
// Mark all allowed
// characters as true
allowed[a[i] - 'a'] = true;
}
char [,]freq = new char[k, 26];
// Initialize the freq array to 0
for(int i = 0; i < k; i++)
for(int j = 0; j < 26; j++)
freq[i, j] = (char)0;
for(int i = 0; i < n; i++)
{
// Increase the frequency
// of each character
freq[i % k, s[i] - 'a'] += (char)1;
}
int ans = 0;
// Total number of periods
// of size K in the String
int totalpositions = n / k;
for(int i = 0; i < k; i++)
{
int maxfrequency = 0;
for(int j = 0; j < 26; j++)
{
// Check if the current character
// is present in allowed
// and whether the current
// frequency is greater than
// all previous frequencies
// for this position
if (freq[i, j] > maxfrequency &&
allowed[j] == true)
maxfrequency = freq[i, j];
}
// Update the answer by
// subtracting the maxfrequency
// from total positions
// if there exist extra character
// at the end of the String
// apart from the n/k characters
// then add 1.
ans += (totalpositions -
maxfrequency +
((i % k < n %
k) ? 1 : 0));
}
Console.Write(ans + "\n");
}
// Driver code
public static void Main(String[] args)
{
String S = "nihsiakyt";
int n = S.Length;
int K = 3;
char []A = { 'n', 'i', 'p', 's', 'q' };
int p = A.Length;
minFlip(S, n, K, A, p);
}
}
// This code is contributed by Rohit_ranjan
Javascript
6
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。