给定两个字符串S和Q 。任务是统计S和T中公共子序列的个数。
例子:
Input : S = “ajblqcpdz”, T = “aefcnbtdi”
Output : 11
Common subsequences are : { “a”, “b”, “c”, “d”, “ab”, “bd”, “ad”, “ac”, “cd”, “abd”, “acd” }
Input : S = “a”, T = “ab”
Output : 1
为了找到两个字符串的公共子序列的数量,比如说 S 和 T,我们通过定义一个二维数组dp[][] 来使用动态规划,其中 dp[i][j] 是字符串S[ 中的公共子序列的数量0…i-1] 和 T[0….j-1]。
现在,我们可以将 dp[i][j] 定义为
= dp[i][j-1] + dp[i-1][j] + 1,当 S[i-1] 等于 T[j-1]
这是因为当 S[i-1] == S[j-1] 时,使用上述事实,所有先前的公共子序列都加倍了,因为它们再追加一个字符。 dp[i][j-1] 和 dp[i-1][j] 都包含 dp[i-1][j-1] ,因此在我们的循环中它被添加了两次,它负责将计数加倍所有以前的公共子序列。在重复中加 1 是针对最新的字符匹配:由 s1[i-1] 和 s2[j-1] 组成的公共子序列
= dp[i-1][j] + dp[i][j-1] – dp[i-1][j-1],当 S[i-1] 不等于 T[j-1]
在这里,我们减去 dp[i-1][j-1] 一次,因为它同时存在于 dp[i][j – 1] 和 dp[i – 1][j] 中并且被添加了两次。
下面是这个方法的实现:
C++
// C++ program to count common subsequence in two strings
#include
using namespace std;
// return the number of common subsequence in
// two strings
int CommomSubsequencesCount(string s, string t)
{
int n1 = s.length();
int n2 = t.length();
int dp[n1+1][n2+1];
for (int i = 0; i <= n1; i++) {
for (int j = 0; j <= n2; j++) {
dp[i][j] = 0;
}
}
// for each character of S
for (int i = 1; i <= n1; i++) {
// for each character in T
for (int j = 1; j <= n2; j++) {
// if character are same in both
// the string
if (s[i - 1] == t[j - 1])
dp[i][j] = 1 + dp[i][j - 1] + dp[i - 1][j];
else
dp[i][j] = dp[i][j - 1] + dp[i - 1][j] -
dp[i - 1][j - 1];
}
}
return dp[n1][n2];
}
// Driver Program
int main()
{
string s = "ajblqcpdz";
string t = "aefcnbtdi";
cout << CommomSubsequencesCount(s, t) << endl;
return 0;
}
Java
// Java program to count common subsequence in two strings
public class GFG {
// return the number of common subsequence in
// two strings
static int CommomSubsequencesCount(String s, String t)
{
int n1 = s.length();
int n2 = t.length();
int dp[][] = new int [n1+1][n2+1];
char ch1,ch2 ;
for (int i = 0; i <= n1; i++) {
for (int j = 0; j <= n2; j++) {
dp[i][j] = 0;
}
}
// for each character of S
for (int i = 1; i <= n1; i++) {
// for each character in T
for (int j = 1; j <= n2; j++) {
ch1 = s.charAt(i - 1);
ch2 = t.charAt(j - 1);
// if character are same in both
// the string
if (ch1 == ch2)
dp[i][j] = 1 + dp[i][j - 1] + dp[i - 1][j];
else
dp[i][j] = dp[i][j - 1] + dp[i - 1][j] -
dp[i - 1][j - 1];
}
}
return dp[n1][n2];
}
// Driver code
public static void main (String args[]){
String s = "ajblqcpdz";
String t = "aefcnbtdi";
System.out.println(CommomSubsequencesCount(s, t));
}
// This code is contributed by ANKITRAI1
}
Python3
# Python3 program to count common
# subsequence in two strings
# return the number of common subsequence
# in two strings
def CommomSubsequencesCount(s, t):
n1 = len(s)
n2 = len(t)
dp = [[0 for i in range(n2 + 1)]
for i in range(n1 + 1)]
# for each character of S
for i in range(1, n1 + 1):
# for each character in T
for j in range(1, n2 + 1):
# if character are same in both
# the string
if (s[i - 1] == t[j - 1]):
dp[i][j] = (1 + dp[i][j - 1] +
dp[i - 1][j])
else:
dp[i][j] = (dp[i][j - 1] + dp[i - 1][j] -
dp[i - 1][j - 1])
return dp[n1][n2]
# Driver Code
s = "ajblqcpdz"
t = "aefcnbtdi"
print(CommomSubsequencesCount(s, t))
# This code is contributed by Mohit Kumar
C#
// C# program to count common
// subsequence in two strings
using System;
class GFG
{
// return the number of common
// subsequence in two strings
static int CommomSubsequencesCount(string s,
string t)
{
int n1 = s.Length;
int n2 = t.Length;
int[,] dp = new int [n1 + 1, n2 + 1];
for (int i = 0; i <= n1; i++)
{
for (int j = 0; j <= n2; j++)
{
dp[i, j] = 0;
}
}
// for each character of S
for (int i = 1; i <= n1; i++)
{
// for each character in T
for (int j = 1; j <= n2; j++)
{
// if character are same in
// both the string
if (s[i - 1] == t[j - 1])
dp[i, j] = 1 + dp[i, j - 1] +
dp[i - 1, j];
else
dp[i, j] = dp[i, j - 1] +
dp[i - 1, j] -
dp[i - 1, j - 1];
}
}
return dp[n1, n2];
}
// Driver code
public static void Main ()
{
string s = "ajblqcpdz";
string t = "aefcnbtdi";
Console.Write(CommomSubsequencesCount(s, t));
}
}
// This code is contributed
// by ChitraNayal
PHP
Javascript
11
时间复杂度: O(n1 * n2)
辅助空间: O(n1 * n2)
来源: StackOverflow
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。