Count number of ways to convert string S to T by performing K cyclic shifts

• Difficulty Level : Hard
• Last Updated : 05 May, 2021

Given two strings S and T and a number K, the task is to count the number of ways to convert string S to string T by performing K cyclic shifts

The cyclic shift is defined as the string S can be split into two non-empty parts X + Y and in one operation we can transform S to Y + X from X + Y.

Note: Since count can be very large print the answer to modulo 109 + 7.
Examples:

Input: S = “ab”, T = “ab”, K = 2
Output:
Explanation:
The only way to do this is to convert [ab to ba] in the first move and then [ba to ab] in the second move.
Input: S = “ababab”, T = “ababab”, K = 1
Output:
Explanation:
One possible way to convert S to T in one move is [ab | abab] -> [ababab], the second way is [abab | ab] -> [ababab]. So there are total two ways.

Approach: This problem can be solved using Dynamic Programming. Let us call a cyclic shift ‘good’ if at the end we are at string T and the vice versa for ‘bad’. Below are the steps:

1. Precompute the number of good(denoted by a) and bad(denoted by b) cyclic shifts.
2. Initialize two dp arrays such that dp1[i] denote the number of ways to get to a good shift in i moves and dp2[i] denotes the number of ways to get to a bad shift in i moves.
3. For transition, we are only concerned about previous state i.e., (i – 1)th state and the answer to this question is dp1[K].
4. So the number of ways to reach a good state in i moves is equal to the number of ways of reaching a good shift in i-1 moves multiplied by (a-1) (as last shift is also good)
5. So the number of ways of reaching a bad shift in i-1 moves multiplied by (a)(as next move can be any of the good shifts).

Below is the recurrence relation for the good and bad shifts:

So for good shifts we have: Similarly, for bad shifts we have: Below is the implementation of above approach:

C++

 // C++ program for the above approach #include using namespace std; #define mod 10000000007   // Function to count number of ways to // convert string S to string T by // performing K cyclic shifts long long countWays(string s, string t,                     int k) {     // Calculate length of string     int n = s.size();       // 'a' is no of good cyclic shifts     // 'b' is no of bad cyclic shifts     int a = 0, b = 0;       // Iterate in the string     for (int i = 0; i < n; i++) {           string p = s.substr(i, n - i)                 + s.substr(0, i);           // Precompute the number of good         // and bad cyclic shifts         if (p == t)             a++;         else             b++;     }       // Initialize two dp arrays     // dp1[i] to store the no of ways to     // get to a good shift in i moves       // dp2[i] to store the no of ways to     // get to a bad shift in i moves     vector dp1(k + 1), dp2(k + 1);       if (s == t) {         dp1 = 1;         dp2 = 0;     }     else {         dp1 = 0;         dp2 = 1;     }       // Calculate good and bad shifts     for (int i = 1; i <= k; i++) {           dp1[i]             = ((dp1[i - 1] * (a - 1)) % mod             + (dp2[i - 1] * a) % mod)             % mod;           dp2[i]             = ((dp1[i - 1] * (b)) % mod             + (dp2[i - 1] * (b - 1)) % mod)             % mod;     }       // Return the required number of ways     return dp1[k]; }   // Driver Code int main() {     // Given Strings     string S = "ab", T = "ab";       // Given K shifts required     int K = 2;       // Function Call     cout << countWays(S, T, K);     return 0; }

Java

 // Java program for above approach class GFG{       static long mod = 10000000007L;   // Function to count number of ways to // convert string S to string T by // performing K cyclic shifts static long countWays(String s, String t,                     int k) {           // Calculate length of string     int n = s.length();       // 'a' is no of good cyclic shifts     // 'b' is no of bad cyclic shifts     int a = 0, b = 0;       // Iterate in the string     for(int i = 0; i < n; i++)     {     String p = s.substring(i, n - i) +                 s.substring(0, i);               // Precompute the number of good     // and bad cyclic shifts     if (p == t)         a++;     else         b++;     }       // Initialize two dp arrays     // dp1[i] to store the no of ways to     // get to a good shift in i moves       // dp2[i] to store the no of ways to     // get to a bad shift in i moves     long dp1[] = new long[k + 1];     long dp2[] = new long[k + 1];       if (s == t)     {         dp1 = 1;         dp2 = 0;     }     else     {         dp1 = 0;         dp2 = 1;     }       // Calculate good and bad shifts     for(int i = 1; i <= k; i++)     {     dp1[i] = ((dp1[i - 1] * (a - 1)) % mod +                 (dp2[i - 1] * a) % mod) % mod;     dp2[i] = ((dp1[i - 1] * (b)) % mod +                 (dp2[i - 1] * (b - 1)) % mod) % mod;     }       // Return the required number of ways     return dp1[k]; }   // Driver code public static void main(String[] args) {           // Given Strings     String S = "ab", T = "ab";       // Given K shifts required     int K = 2;       // Function Call     System.out.print(countWays(S, T, K)); } }   // This code is contributed by Pratima Pandey

Python3

 # Python3 program for the above approach mod = 1000000007   # Function to count number of ways # to convert string S to string T by # performing K cyclic shifts def countWays(s, t, k):           # Calculate length of string     n = len(s)           # a is no. of good cyclic shifts     # b is no. of bad cyclic shifts     a = 0     b = 0           # Iterate in string     for i in range(n):         p = s[i : n - i + 1] + s[: i + 1]                   # Precompute the number of good         # and bad cyclic shifts         if(p == t):             a += 1         else:             b += 1                   # Initialize two dp arrays     # dp1[i] to store the no of ways to     # get to a goof shift in i moves           # dp2[i] to store the no of ways to     # get to a bad shift in i moves     dp1 =  * (k + 1)     dp2 =  * (k + 1)           if(s == t):         dp1 = 1         dp2 = 0     else:         dp1 = 0         dp2 = 1               # Calculate good and bad shifts         for i in range(1, k + 1):         dp1[i] = ((dp1[i - 1] * (a - 1)) % mod +                 (dp2[i - 1] * a) % mod) % mod           dp2[i] = ((dp1[i - 1] * (b)) % mod +                 (dp2[i - 1] * (b - 1)) % mod) % mod                           # Return the required number of ways     return(dp1[k])       # Driver Code   # Given Strings S = 'ab' T = 'ab'   # Given K shifts required K = 2   # Function call print(countWays(S, T, K))   # This code is contributed by Arjun Saini

C#

 // C# program for the above approach using System;   class GFG{       static long mod = 10000000007L;   // Function to count number of ways to // convert string S to string T by // performing K cyclic shifts static long countWays(string s, string t,                       int k) {           // Calculate length of string     int n = s.Length;       // 'a' is no of good cyclic shifts     // 'b' is no of bad cyclic shifts     int a = 0, b = 0;       // Iterate in the string     for(int i = 0; i < n; i++)     {         string p = s.Substring(i, n - i) +                    s.Substring(0, i);                   // Precompute the number of good         // and bad cyclic shifts         if (p == t)             a++;         else             b++;     }       // Initialize two dp arrays     // dp1[i] to store the no of ways to     // get to a good shift in i moves       // dp2[i] to store the no of ways to     // get to a bad shift in i moves     long []dp1 = new long[k + 1];     long []dp2 = new long[k + 1];       if (s == t)     {         dp1 = 1;         dp2 = 0;     }     else     {         dp1 = 0;         dp2 = 1;     }       // Calculate good and bad shifts     for(int i = 1; i <= k; i++)     {         dp1[i] = ((dp1[i - 1] * (a - 1)) % mod +                   (dp2[i - 1] * a) % mod) % mod;         dp2[i] = ((dp1[i - 1] * (b)) % mod +                   (dp2[i - 1] * (b - 1)) % mod) % mod;     }       // Return the required number of ways     return dp1[k]; }   // Driver code public static void Main(string[] args) {           // Given Strings     string S = "ab", T = "ab";       // Given K shifts required     int K = 2;       // Function call     Console.Write(countWays(S, T, K)); } }   // This code is contributed by rutvik_56

Javascript



Output:

1

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :