给定一个大小为N的字符串S和一个正整数K (其中N % K = 0) ,任务是找到需要被替换的最少字符数,使得该字符串是K周期且长度为K 的周期字符串必须是回文。
例子:
Input: S = “abaaba”, K = 3
Output: 0
Explanation: The given string is already K-periodic and the periodic string “aba” is palindromic.
Input: S = “abaaba”, K = 2
Output: 2
Explanation: By changing the characters at index 1 and 4 to ‘a’, the updated sting “aaaaaa” is K-periodic and the periodic string “aa” is palindromic. Therefore, minimum changes required is 2.
方法:想法是从给定的字符串索引创建一个 Graph 并执行 DFS Traversals 以找到所需的更改数量。请按照以下步骤解决此问题:
- 将变量total初始化为0以存储所需更改的计数。
- 根据给定的条件,从字符串和最终字符串的所有字符在位置i, K − i +1, K + i, 2K − i +1, 2K + i, 3K − i + 1, …对于所有1 ≤ i ≤ K应该是相等的。
- 迭代范围[0, N]并在索引i和(N – i – 1)之间添加一条无向边。
- 迭代范围[0, N – M]并在索引i和(i + K)之间添加一条无向边。
- 为了尽量减少所需的操作次数,使所有字母等于出现在这些位置最多的字母,这可以通过对字符串执行 DFS 遍历来轻松找到。
- 对所有未访问的节点在创建的图上执行DFS 遍历:
- 在该遍历中的访问字符中找到频率最大的最大元素(比如maxFrequency )。
- 通过DFS Traversal中所有访问字符的计数与上一步中的最大频率之差更新字符变化的总数。
- 完成上述步骤后,打印总计的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include "bits/stdc++.h"
using namespace std;
// Function to add an edge to graph
void addEdge(vector adj[], int u,
int v)
{
adj[u].push_back(v);
adj[v].push_back(u);
}
// Function to perform DFS traversal on the
// graph recursively from a given vertex u
void DFS(int u, vector adj[],
int& cnt, vector& visited,
int fre[], string S)
{
// Visit the current vertex
visited[u] = true;
// Total number of nodes
// in this component
cnt++;
// Increment the frequency of u
fre[S[u] - 'a']++;
for (int i = 0;
i < adj[u].size(); i++) {
if (!visited[adj[u][i]]) {
DFS(adj[u][i], adj, cnt,
visited, fre, S);
}
}
}
// Function for finding the minimum
// number changes required in given string
int minimumOperations(string& S, int m)
{
int V = 100;
vector adj[V];
int total = 0, N = S.length();
// Form the edges according to the
// given conditions
for (int i = 0; i < N; i++) {
addEdge(adj, i, N - i - 1);
addEdge(adj, N - i - 1, i);
}
for (int i = 0; i < N - m; i++) {
addEdge(adj, i, i + m);
addEdge(adj, i + m, i);
}
// Find minimum number of operations
vector visited(V, 0);
for (int i = 0; i < N; i++) {
// Frequency array for finding
// the most frequent character
if (!visited[i]) {
// Frequency array for finding
// the most frequent character
int fre[26] = { 0 };
int cnt = 0, maxx = -1;
DFS(i, adj, cnt, visited, fre, S);
// Finding most frequent character
for (int j = 0; j < 26; j++)
maxx = max(maxx, fre[j]);
// Change rest of the characters
// to most frequent one
total += cnt - maxx;
}
}
// Print total number of changes
cout << total;
}
// Driver Code
int main()
{
string S = "abaaba";
int K = 2;
// Function Call
minimumOperations(S, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to add an edge to graph
static void addEdge(Vector adj[], int u,
int v)
{
adj[u].add(v);
adj[v].add(u);
}
static int cnt = 0;
static boolean[] visited;
// Function to perform DFS traversal on the
// graph recursively from a given vertex u
static void DFS(int u, Vector adj[],
int fre[], String S)
{
// Visit the current vertex
visited[u] = true;
// Total number of nodes
// in this component
cnt++;
// Increment the frequency of u
fre[S.charAt(u) - 'a']++;
for(int i = 0; i < adj[u].size(); i++)
{
if (!visited[adj[u].get(i)])
{
DFS(adj[u].get(i), adj, fre, S);
}
}
}
// Function for finding the minimum
// number changes required in given String
static void minimumOperations(String S, int m)
{
int V = 100;
@SuppressWarnings("unchecked")
Vector []adj = new Vector[V];
int total = 0, N = S.length();
for(int i = 0; i < adj.length; i++)
adj[i] = new Vector();
// Form the edges according to the
// given conditions
for(int i = 0; i < N; i++)
{
addEdge(adj, i, N - i - 1);
addEdge(adj, N - i - 1, i);
}
for(int i = 0; i < N - m; i++)
{
addEdge(adj, i, i + m);
addEdge(adj, i + m, i);
}
// Find minimum number of operations
visited = new boolean[V];
for(int i = 0; i < N; i++)
{
// Frequency array for finding
// the most frequent character
if (!visited[i])
{
// Frequency array for finding
// the most frequent character
int fre[] = new int[26];
cnt = 0;
int maxx = -1;
DFS(i, adj, fre, S);
// Finding most frequent character
for(int j = 0; j < 26; j++)
maxx = Math.max(maxx, fre[j]);
// Change rest of the characters
// to most frequent one
total += cnt - maxx;
}
}
// Print total number of changes
System.out.print(total);
}
// Driver Code
public static void main(String[] args)
{
String S = "abaaba";
int K = 2;
// Function Call
minimumOperations(S, K);
}
}
// This code is contributed by aashish1995
Python3
# Python3 program for the above approach
import sys
sys.setrecursionlimit(1500)
# Function to add an edge to graph
def addEdge(u, v):
global adj
adj[u].append(v)
adj[v].append(u)
# Function to perform DFS traversal on the
# graph recursively from a given vertex u
def DFS(u, fre, S):
global visited, adj, cnt
# Visit the current vertex
visited[u] = 1
# Total number of nodes
# in this component
cnt += 1
# Increment the frequency of u
fre[ord(S[u]) - ord('a')] += 1
for i in adj[u]:
if (visited[i] == 0):
DFS(i, fre, S)
# Function for finding the minimum
# number changes required in given string
def minimumOperations(S, m):
global adj, visited, cnt
total, N = 0, len(S)
# Form the edges according to the
# given conditions
for i in range(N):
addEdge(i, N - i - 1)
addEdge(N - i - 1, i)
for i in range(N-m):
addEdge(i, i + m)
addEdge(i + m, i)
for i in range(N):
# Frequency array for finding
# the most frequent character
if (not visited[i]):
# Frequency array for finding
# the most frequent character
fre = [0] * 26
cnt, maxx = 0, -1
DFS(i, fre, S)
# Finding most frequent character
for j in range(26):
maxx = max(maxx, fre[j])
# Change rest of the characters
# to most frequent one
total += cnt - maxx
# Print total number of changes
print (total)
# Driver Code
if __name__ == '__main__':
adj = [[] for i in range(101)]
visited, cnt = [0 for i in range(101)], 0
S = "abaaba"
K = 2
# Function Call
minimumOperations(S, K)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to add an edge to graph
static void addEdge(List []adj, int u,
int v)
{
adj[u].Add(v);
adj[v].Add(u);
}
static int cnt = 0;
static bool[] visited;
// Function to perform DFS traversal on the
// graph recursively from a given vertex u
static void DFS(int u, List []adj,
int []fre, String S)
{
// Visit the current vertex
visited[u] = true;
// Total number of nodes
// in this component
cnt++;
// Increment the frequency of u
fre[S[u] - 'a']++;
for(int i = 0; i < adj[u].Count; i++)
{
if (!visited[adj[u][i]])
{
DFS(adj[u][i], adj, fre, S);
}
}
}
// Function for finding the minimum
// number changes required in given String
static void minimumOperations(String S, int m)
{
int V = 100;
List []adj = new List[V];
int total = 0, N = S.Length;
for(int i = 0; i < adj.Length; i++)
adj[i] = new List();
// Form the edges according to the
// given conditions
for(int i = 0; i < N; i++)
{
addEdge(adj, i, N - i - 1);
addEdge(adj, N - i - 1, i);
}
for(int i = 0; i < N - m; i++)
{
addEdge(adj, i, i + m);
addEdge(adj, i + m, i);
}
// Find minimum number of operations
visited = new bool[V];
for(int i = 0; i < N; i++)
{
// Frequency array for finding
// the most frequent character
if (!visited[i])
{
// Frequency array for finding
// the most frequent character
int []fre = new int[26];
cnt = 0;
int maxx = -1;
DFS(i, adj, fre, S);
// Finding most frequent character
for(int j = 0; j < 26; j++)
maxx = Math.Max(maxx, fre[j]);
// Change rest of the characters
// to most frequent one
total += cnt - maxx;
}
}
// Print total number of changes
Console.Write(total);
}
// Driver Code
public static void Main(String[] args)
{
String S = "abaaba";
int K = 2;
// Function Call
minimumOperations(S, K);
}
}
// This code is contributed by aashish1995
输出:
2
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。