Minimum number of swaps required to make the string K periodic

Given a string S of length N, and an array A, consisting of lowercase letters. Also given a positive integer K. the task is to find the minimum number of swaps required (between S and A) to make string S K periodic.

Note:

  • A string is said to be K periodic, if for each position i in the string S[i] = S[i+K].
  • In one move, only one character of S can be swapped with a character of A.
  • The characters in A can be used more than once.

Examples:

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.



Approach: This problem can be solved with help of frequency counting and hashing.

  1. To solve the problem mentioned above we use a 2-dimensional array freq[K][26] to store frequency of characters at position j % K for all 0 ≤ j < N.
  2. Use a boolean array to mark all characters present in array A.
  3. For all characters in range 0 to K there will be N / K or (N / K + 1) characters which should be same.
  4. So for all such characters we check which character has the maximum frequency at position i and is also present in array A.
  5. Add that to the answer, i.e. (N / K - maxfrequency).
  6. We will also add 1 to the answer if i % K < N % K because there will be N / K + 1 characters for all such characters i.

Below is the implementation of above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ code to find the minimum
// number of swaps required to
// make the string K periodic
  
#include <bits/stdc++.h>
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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

6

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.