以 S 作为子序列的 N 个长度字符串的计数
给定一个字符串S和一个整数N ,任务是计算仅由小写字符组成的长度为N的字符串的数量 其中有S作为其子序列之一。
注意:由于答案可能非常大,因此以 10^9+7 为模返回。
例子:
Input: N = 3, S = “abc”
Output: 1
Explanation: There are only 1 subsequences of length 3 which is “abc”.
Input: N = 5, S = “aba”
Output: 6376
方法:这个问题可以根据以下观察来解决:
Assume, the length of string S (say X) is less at most N. Then the first occurrence of S in any string must end between [X, N].
- Now, suppose the first occurrence of S ends at index i (where X ≤ i ≤ N), then we can place any character between [i+1, N]. The number of ways to do it is 26N-i.
- Now, the Number of ways to end the first occurrence of string S at ith index is i-1CX-1 * 25i-X * 26N-i because of the following reason:
- If the last character of S is at ith index then X-1 characters must be placed in the first i-1 positions.
- Number of ways to choose X-1 indices to place the first X-1 characters of the string S before ith index is i-1CX-1 .
- So each of the remaining i-X positions can be filled by any of the 25 characters other than the last character of S (because if the last character of S is chosen then the last character of S will be before i which is not consistent with the assumption).Therefore the number of ways for this is 25i-X.
- So, the total number of ways such that S end at ith index is i-1CX-1 * 25i-X * 26N-i.
按照下面提到的步骤使用上述观察解决问题:
- 从i = X 迭代到 N :
- 假设S结束于i 。
- 根据上面的公式计算可能的方法数。
- 将此添加到答案的最终计数中。
- 返回最终答案。
下面是上述方法的实现:
C++
// C++ program for Count the number of strings of
// length N which have string S as subsequence
#include
using namespace std;
// Initialise mod value.
const int mod = 1e9 + 7;
// Binary exponentiation
long long int power(long long int x, long long int y,
long long int p)
{
long long int res = 1;
x = x % p;
if (x == 0)
return 0;
while (y > 0) {
if (y & 1) {
res = (res * x) % p;
}
y = y >> 1;
x = (x * x) % p;
}
return res;
}
// Calculate nCr for given n and r
long long int nCr(int n, int r, long long int factorials[])
{
if (r > n)
return 0;
long long int answer = factorials[n];
// Divide factorials[r]
answer *= power(factorials[r], mod - 2, mod);
answer %= mod;
// Divide factorials[n-r]
answer *= power(factorials[n - r], mod - 2, mod);
answer %= mod;
return answer;
}
// Function to count number of possible strings
int numberOfStrings(int N, string S)
{
int X = S.length();
// if N is less than X, then just print 0.
if (X > N) {
return 0;
}
// Precalculate factorials
long long int factorials[N + 1];
factorials[0] = 1;
for (int i = 1; i <= N; i++) {
factorials[i] = factorials[i - 1] * i;
factorials[i] %= mod;
}
// Store answer
long long int answer = 0;
// Iterate over possible ending
// indices for first subsequence of S
// in the string
for (int i = X; i <= N; i++) {
long long int add
= nCr(i - 1, X - 1, factorials);
add *= power(26, N - i, mod);
add %= mod;
add *= power(25, i - X, mod);
add %= mod;
answer += add;
if (answer >= mod)
answer -= mod;
}
return (int)answer;
}
// Driver Code
int main()
{
int N = 5;
string S = "aba";
cout << numberOfStrings(N, S);
return 0;
}
Java
// Java program for Count the number of strings of
// length N which have string S as subsequence
import java.io.*;
class GFG {
// Initialise mod value.
static int mod = 1000000007;
// Binary exponentiation
public static long power(long x, long y, long p)
{
long res = 1;
x = x % p;
if (x == 0)
return 0;
while (y > 0) {
if ((y & 1) != 0) {
res = (res * x) % p;
}
y = y >> 1;
x = (x * x) % p;
}
return res;
}
// Calculate nCr for given n and r
public static long nCr(int n, int r, long factorials[])
{
if (r > n)
return 0;
long answer = factorials[n];
// Divide factorials[r]
answer *= power(factorials[r], mod - 2, mod);
answer %= mod;
// Divide factorials[n-r]
answer *= power(factorials[n - r], mod - 2, mod);
answer %= mod;
return answer;
}
// Function to count number of possible strings
public static int numberOfStrings(int N, String S)
{
int X = S.length();
// if N is less than X, then just print 0.
if (X > N) {
return 0;
}
// Precalculate factorials
long factorials[] = new long[N + 1];
factorials[0] = 1;
for (int i = 1; i <= N; i++) {
factorials[i] = factorials[i - 1] * i;
factorials[i] %= mod;
}
// Store answer
long answer = 0;
// Iterate over possible ending
// indices for first subsequence of S
// in the string
for (int i = X; i <= N; i++) {
long add = nCr(i - 1, X - 1, factorials);
add *= power(26, N - i, mod);
add %= mod;
add *= power(25, i - X, mod);
add %= mod;
answer += add;
if (answer >= mod)
answer -= mod;
}
return (int)answer;
}
public static void main(String[] args)
{
int N = 5;
String S = "aba";
System.out.print(numberOfStrings(N, S));
}
}
// This code is contributed by Rohit Pradhan.
Python3
# python3 program for Count the number of strings of
# length N which have string S as subsequence
# Initialise mod value.
mod = int(1e9 + 7)
# Binary exponentiation
def power(x, y, p):
res = 1
x = x % p
if (x == 0):
return 0
while (y > 0):
if (y & 1):
res = (res * x) % p
y = y >> 1
x = (x * x) % p
return res
# Calculate nCr for given n and r
def nCr(n, r, factorials):
if (r > n):
return 0
answer = factorials[n]
# Divide factorials[r]
answer *= power(factorials[r], mod - 2, mod)
answer %= mod
# Divide factorials[n-r]
answer *= power(factorials[n - r], mod - 2, mod)
answer %= mod
return answer
# Function to count number of possible strings
def numberOfStrings(N, S):
X = len(S)
# if N is less than X, then just print 0.
if (X > N):
return 0
# Precalculate factorials
factorials = [0 for _ in range(N + 1)]
factorials[0] = 1
for i in range(1, N+1):
factorials[i] = factorials[i - 1] * i
factorials[i] %= mod
# Store answer
answer = 0
# Iterate over possible ending
# indices for first subsequence of S
# in the string
for i in range(X, N+1):
add = nCr(i - 1, X - 1, factorials)
add *= power(26, N - i, mod)
add %= mod
add *= power(25, i - X, mod)
add %= mod
answer += add
if (answer >= mod):
answer -= mod
return answer
# Driver Code
if __name__ == "__main__":
N = 5
S = "aba"
print(numberOfStrings(N, S))
# This code is contributed by rakeshsahni
输出
6376
时间复杂度: O(N * logN)
辅助空间: O(N)