给定两个字符串S和T以及一个数字K ,任务是计算通过执行K个循环移位将字符串S转换为字符串T的方式的数量。
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.
注意:由于计数可能非常大,请打印模10 9 + 7的答案。
例子:
Input: S = “ab”, T = “ab”, K = 2
Output: 1
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: 2
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.
方法:可以使用动态编程解决此问题。如果最后我们在字符串T处,而在“坏”处反之亦然,则让我们将循环移位称为“好” 。步骤如下:
- 预计算好(用a表示)和坏(用b表示)循环移位的次数。
- 初始化两个DP阵列使得DP1 [I]表示的方式编号,以获得一个良好的移位在我移动和DP2 [i]表示的方式来获得到一个坏的转移在我的移动的数目。
- 对于过渡,我们仅关注先前的状态,即第(i – 1)个状态,并且对该问题的答案是dp1 [K] 。
- 因此,在i个动作中达到良好状态的方式数量等于在i-1个动作中达到良好状态的方式数量乘以(a-1) (因为最后的转换效果也不错)
- 因此,在i-1个移动中达到不良移动的方式数量乘以(a) (因为下一移动可以是任何一个良好的移动)。
以下是好班和坏班的递归关系:
So for good shifts we have:
Similarly, for bad shifts we have:
下面是上述方法的实现:
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[0] = 1;
dp2[0] = 0;
}
else {
dp1[0] = 0;
dp2[0] = 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[0] = 1;
dp2[0] = 0;
}
else
{
dp1[0] = 0;
dp2[0] = 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 = [0] * (k + 1)
dp2 = [0] * (k + 1)
if(s == t):
dp1[0] = 1
dp2[0] = 0
else:
dp1[0] = 0
dp2[0] = 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[0] = 1;
dp2[0] = 0;
}
else
{
dp1[0] = 0;
dp2[0] = 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
1
时间复杂度: O(N)
辅助空间: O(K)