Algorithm 不同的子序列
从 给定一个字符串S和一个字符串T,计算不同的 S中T的子序列 字符串的子序列是由 通过删除某些字符(可以是无字符)来创建原始字符串 不干扰其余字符的相对位置。 (即,“ACE”是“ABCDE”的子序列,而“AEC”不是) 下面是一个例子:S=“rabbit”,T=“rabbit” 返回3 我看到了一个非常好的DP解决方案,但是,我很难理解它,任何人都可以解释这个DP是如何工作的Algorithm 不同的子序列,algorithm,dynamic-programming,Algorithm,Dynamic Programming,从 给定一个字符串S和一个字符串T,计算不同的 S中T的子序列 字符串的子序列是由 通过删除某些字符(可以是无字符)来创建原始字符串 不干扰其余字符的相对位置。 (即,“ACE”是“ABCDE”的子序列,而“AEC”不是) 下面是一个例子:S=“rabbit”,T=“rabbit” 返回3 我看到了一个非常好的DP解决方案,但是,我很难理解它,任何人都可以解释这个DP是如何工作的 int numDistinct(string S, string T) { vector<int&g
int numDistinct(string S, string T) {
vector<int> f(T.size()+1);
//set the last size to 1.
f[T.size()]=1;
for(int i=S.size()-1; i>=0; --i){
for(int j=0; j<T.size(); ++j){
f[j]+=(S[i]==T[j])*f[j+1];
printf("%d\t", f[j] );
}
cout<<"\n";
}
return f[0];
}
int numDistinct(字符串S,字符串T){
向量f(T.size()+1);
//将最后一个大小设置为1。
f[T.size()]=1;
对于(int i=S.size()-1;i>=0;--i){
对于(int j=0;j,首先,试着自己解决问题,想出一个简单的实现:
假设s.length=m
和T.length=n
。让我们为s
的子串写s{i}
,从i
开始。例如,如果s=“abcde”
,s{0}=“abcde”
,s{4}=“e
,和s{5},我们对使用类似的定义
让N[i][j]
成为S{i}
和T{j}
的不同子序列。我们对N[0][0]
感兴趣(因为它们都是完整的字符串)
有两个简单的例子:N[i][N]
对于任何i
和N[m][j]
对于j我认为答案很好,但有些地方可能不正确
我认为我们应该向后迭代I
和j
。然后我们将数组N
更改为数组f
,我们向前循环j
以避免与最后得到的结果重叠
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
N[i][j] = N[i+1][j] + N[i+1][j+1];
} else {
N[i][j] = N[i+1][j];
}
}
}
用于(int i=m-1;i>=0;i--){
对于(int j=0;j
我不明白你的最后一句话。你能回顾一下你写的内容并确保它有意义吗?我错了二维数组编写的代码也是正确的,向前和向后的j都是正确的。但是当我们把二维数组改成一维数组时,我们必须向前循环j,我们不能在最后一个循环中得到结果(这里是j+1),最后一个循环的结果存储在数组f中,我们有“f[j]+=(S[i]==T[j])*f[j+1]”,我们向前循环j,所以我们确保在计算f[j]时f[j+1]没有被修改。@S.H。你可以把它看作是(int i=0;如果这是一个愚蠢的问题,我很抱歉,但是dp如何确保只计算不同的子序列?@frodo每个子序列都是一个精确匹配的结果:一些S
的字母与T
的字母匹配,而另一些则不匹配。该算法循环遍历S
的字母,并将输出相加当它与该字母匹配时,以及当它与t
中的字母不匹配时,都会出现错误。没有第三个选项,因此不会重复计算。我希望这不会让您更加困惑;-)很好的解释!没有多少算法问题得到了回答,更不用说有如此高的质量了。我希望看到更多!
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
N[i][j] = N[i+1][j] + N[i+1][j+1];
} else {
N[i][j] = N[i+1][j];
}
}
}
f[j] = 0, for 0 <= j < n
f[n] = 1
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
f[j] = f[j] + f[j+1];
} else {
f[j] = f[j];
}
}
}
if (S[i] == T[j]) {
f[j] += f[j+1];
}
f[j] += (S[i] == T[j]) * f[j+1];
f[n] = 1
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
f[j] += (S[i] == T[j]) * f[j+1];
}
}
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
N[i][j] = N[i+1][j] + N[i+1][j+1];
} else {
N[i][j] = N[i+1][j];
}
}
}