这题有有意思,比前面的题好多了,刚开始时理解题意有误,就是没明白什么意思,看了别人的博客才明白。之后就是方法的问题,递归,动态规划,然后是动态规划的优化,不优化的动态规划不通过。所谓的优化,其实就是用一维数组代替DP的二维数组,dp式子dp[i][j]=dp[i-1][j-1]+dp[i-1][j](S[i]==T[j])时;dp[i][j]=dp[i-1][j](S[i]!=T[j])时;只要是这种形式的,有一维的索引下标每次都递减的情况就可以优化,不满足这样的式子不能优化。还要注意的是优化后的式子if (S[i-1]==T[j-1]) dp[j] = dp[j-1] + dp[j];for循环j要从大到小,否则回新的值会覆盖原来的值,等式右边是原来的值,左侧是更新的值。三种方法代码如下:
// LeetCode_Distinct Subsequences.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
int numDistinctRecursive(string &S,int i,string &T,int j)
{
if(i<j)
return 0;
if(j<0)
return 1;
if(i==j&&S[i]!=T[j])
return 0;
if(S[i]==T[j])
return numDistinctRecursive(S,i-1,T,j-1) + numDistinctRecursive(S,i-1,T,j);
else
return numDistinctRecursive(S,i-1,T,j);
}
int numDistinct(string S, string T) {
if(S.length()<T.length())
return 0;
if(S.empty()||T.empty())
return 0;
return numDistinctRecursive(S,S.length()-1,T,T.length()-1);
}
int numDistinct02(string S, string T) {
int lens = S.length();
int lent = T.length();
if(lens<lent)
return 0;
if(lens==0||lent==0)
return 0;
int dp[500][500];
if(S[0]==T[0])
dp[0][0] = 1;
else
dp[0][0] = 0;
for (int k=1;k<lens;k++)
{
if (S[k]==T[0])
dp[k][0] = dp[k-1][0] + 1;
else
dp[k][0] = dp[k-1][0];
}
for (int j=1;j<lent;j++)
{
for (int i=0;i<lens;i++)
{
if(j>i)
dp[i][j] = 0;
else
{
if (S[i]==T[j])
dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
else
dp[i][j] = dp[i-1][j];
}
}
}
return dp[lens-1][lent-1];
}
int numDistinct03(string S, string T) {
int lens = S.length();
int lent = T.length();
if(lens<lent)
return 0;
if(lens==0||lent==0)
return 0;
int dp[10000];
dp[0] = 1;
for (int k=1;k<=lent;k++)
dp[k] = 0;
for (int i=1;i<=lens;i++)
{
for (int j=lent;j>=1;j--)// otherwise overlapped
{
if (S[i-1]==T[j-1])
dp[j] = dp[j-1] + dp[j];
}
}
return dp[lent];
}
int _tmain(int argc, _TCHAR* argv[])
{
string s,t;
while(cin>>s&&cin>>t)
{
cout<<numDistinct(s,t)<<endl;
cout<<numDistinct02(s,t)<<endl;
cout<<numDistinct03(s,t)<<endl;
}
system("pause");
return 0;
}