Minimum count of distinct Strings by Rotating and Changing characters
Given a string S of length N and an integer K. The task is to find the minimum count of distinct strings by changing at most K characters of the string (into any other lowercase letters) and by rotating the string left any number of times.
Examples:
Input : N = 4, S = “abac”, K = 1
Output: 2
Explanation: In the initial string, the number of distinct strings after left rotations is 4, i.e abac -> baca ->acab ->caba. On changing ‘c’ to ‘b’, the string becomes “abab”. For the updated string, the number of distinct strings after left rotations is 2, i.e. abab -> baba. It can be checked that this is the minimum possible number of distinct strings after left rotations by performing the given operation K(=1) times.Input : N = 10, S = “cccccccccc”, K = 0
Output : 0
Approach: This can be solved with the following idea:
For string S, consider the smallest integer D, which is the divisor of S such that S[i] = S[i + D] =….= S[N – D + i] for all i = 1 to D. Since, this observation is always true for D = N, so such a D always exist. In such a case, the number of distinct strings achievable by left rotation would be D.
Follow the steps to solve the problem:
- Iterate through all the divisors of N.
- For the current divisor (say ‘l’), calculate the minimum number of characters in the string that need to be changed (say “now”) such that the string satisfies the condition mentioned in the observation.
- This can be easily calculated with the help of an array (say cnt[]) that stores the number of occurrences of each character in the string at a distance of ‘l’.
- If the calculated value of “now” is smaller than K, then return that, else proceed for the next iteration (i.e. check the same for the next divisor of N).
Below is the code based on the above approach:
C++
// C++ code for the above approach #include <bits/stdc++.h> using namespace std; #define int long long // Function Change any K characters of // string S such that number of distinct // strings after left rotations is minimized int minimizeNumberOfStrings( int N, int K, string S) { // Initialize "ans" by N for // worst case int ans = N; // Iterate through l=1 to N. If l is // divisor of N, proceed into the loop for ( int l = 1; l <= N; l++) if (N % l == 0) { // Variable "now" stores the // value of the number of // characters to be change in // the string such the required // answer becomes equal to l int now = 0; // Calculation of "now" for ( int i = 0; i < l; i++) { // cnt[] array stores the // number of times each // character occurs in S // at the difference of // indices = l int cnt[26] = {}; // "mx" stores the value of // maximum element of cnt[] int mx = 0; for ( int j = i; j < N; j += l) mx = max(mx, ++cnt[S[j] - 'a' ]); // "curr" basically represents // the number of characters // in S from index i to N, // that we are assuming to // become same int curr = N / l; // "now" is the difference // of curr and mx now += curr - mx; } // If value of "now" is less // than or equal to K, make // the "ans" equal to l and // break the loop if (now <= K) { ans = l; break ; } } // Return the final "ans" return ans; } // Driver code int32_t main() { int N = 4, K = 1; string S = "abac" ; // Function call int answer = minimizeNumberOfStrings(N, K, S); cout << answer; return 0; } |
Java
// Java code for the above approach import java.util.*; class GFG { // Function Change any K characters of // string S such that number of distinct // strings after left rotations is minimized public static long minimizeNumberOfStrings( int N, int K, String S) { // Initialize "ans" by N for // worst case long ans = N; // Iterate through l=1 to N. If l is // divisor of N, proceed into the loop for ( int l = 1 ; l <= N; l++) { if (N % l == 0 ) { // Variable "now" stores the // value of the number of // characters to be change in // the string such the required // answer becomes equal to l long now = 0 ; // Calculation of "now" for ( int i = 0 ; i < l; i++) { // cnt[] array stores the // number of times each // character occurs in S // at the difference of // indices = l int [] cnt = new int [ 26 ]; // "mx" stores the value of // maximum element of cnt[] int mx = 0 ; for ( int j = i; j < N; j += l) { mx = Math.max( mx, ++cnt[S.charAt(j) - 'a' ]); } // "curr" basically represents // the number of characters // in S from index i to N, // that we are assuming to // become same int curr = N / l; // "now" is the difference // of curr and mx now += curr - mx; } // If value of "now" is less // than or equal to K, make // the "ans" equal to l and // break the loop if (now <= K) { ans = l; break ; } } } // Return the final "ans" return ans; } // Driver code public static void main(String[] args) { int N = 4 , K = 1 ; String S = "abac" ; // Function call long answer = minimizeNumberOfStrings(N, K, S); System.out.println(answer); } } |
Python3
# Function to change any K characters of string S # such that the number of distinct strings after # left rotations is minimized def minimizeNumberOfStrings(N, K, S): # Initialize "ans" by N for worst case ans = N # Iterate through l=1 to N//2 (excluding N) # If l is a divisor of N, proceed into the loop for l in range ( 1 , N / / 2 + 1 ): if N % l = = 0 : # Variable "now" stores the value of the number # of characters to be change in the string such # the required answer becomes equal to l now = 0 # Calculation of "now" for i in range (l): # cnt[] array stores the number of times # each character occurs in S at the # difference of indices = l cnt = [ 0 ] * 26 mx = 0 for j in range (i, N, l): cnt[ ord (S[j]) - ord ( 'a' )] + = 1 mx = max (mx, cnt[ ord (S[j]) - ord ( 'a' )]) # curr basically represents the number of # characters in S from index i to N, that we # are assuming to become the same curr = N / / l # "now" is the difference of curr and mx now + = curr - mx # If value of "now" is less than or equal to K, # make the "ans" equal to l and break the loop if now < = K: ans = l break # Return the final "ans" return ans # Driver code if __name__ = = '__main__' : N = 4 K = 1 S = "abac" # Function call answer = minimizeNumberOfStrings(N, K, S) print (answer) |
Javascript
function minimizeNumberOfStrings(N, K, S) { let ans = N; // Initialize "ans" by N for worst case for (let l = 1; l <= N; l++) { if (N % l == 0) { // If l is a divisor of N, proceed into the loop let now = 0; // Variable "now" stores the value of the number of characters to be changed in the string such that the required answer becomes equal to l for (let i = 0; i < l; i++) { let cnt = new Array(26).fill(0); // cnt[] array stores the number of times each character occurs in S at the difference of indices = l let mx = 0; // "mx" stores the value of maximum element of cnt[] for (let j = i; j < N; j += l) { mx = Math.max(mx, ++cnt[S.charCodeAt(j) - 'a' .charCodeAt()]); // Calculate the maximum count of any character in the substring of length l starting from i and jumping l indices } let curr = Math.floor(N / l); // "curr" basically represents the number of characters in S from index i to N that we are assuming to become same now += curr - mx; // "now" is the difference of curr and mx, representing the number of characters to be changed to make them all same } if (now <= K) { // If value of "now" is less than or equal to K, make the "ans" equal to l and break the loop ans = l; break ; } } } return ans; // Return the final "ans" } // example usage: let N = 4, K = 1; let S = "abac" ; let answer = minimizeNumberOfStrings(N, K, S); console.log(answer); |
2
Time Complexity: O(N2)
Auxiliary Space: O(1)
Please Login to comment...