Minimum replacements required to obtain a K-periodic palindromic string

Given a string S of length N and an integer K, the task is to find the minimum character replacements required to make the string palindromic as well as K-periodic.

Examples:

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.

Approach: To minimize the number of changes required to make in the string, observe the following property of the transformed string which is palindromic and K-periodic:



The problem reduces to making all the characters equal to the one which appears the maximum number of times at these positions in the given string. Follow the steps below to solve the above problem: 

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
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<char, int> 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;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Character, Integer> 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<Character,
                      Integer> 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<char,
                   int> mp = new Dictionary<char,
                                            int>();
 
        // 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<char,
                             int> 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
chevron_right

Output: 
2










 

Time Complexity: O(N)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




Article Tags :