LeetCode 115. 不同的子序列

基本思想:

本来想用DFS加剪枝,发现不太好写,此次题目没想到还是采用dp思想;

 

 

DP方程的问题:

主要难在方程的构建,主旨思想是通过区间判别;

其中dp为二维数组,其中dp[i][j]为s[0:i]和t[0:j]中元素相等个数;

 

对于0~i个元素,如果s[i]=t[j],可以产生两种0-i-1子序列递归判定思想:

1.如果接受s[i]=t[j],则直接加上dp[i-1][j-1],即判断之前的子序列;

2.如果不接受s[i]=t[j],则判断s[0:i-1]和t[0:j]相同个数(因为t是固定的判定序列,无多于元素);

所以整体的dp状态转移方程为:

dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

同理,如果s[i]!=t[j],dp转移方程和第二种情况相同,为:

dp[i][j] = dp[i - 1][j];

 

DP边界问题:

dp边界分为两种情况:

1.当t的j=0时,只有s清除为0这一种情况,此时s,t完美匹配一次,所以dp[i][0]=1;

2.当s的i=0时,无论什么时候都无法匹配,所以dp[0][j]=0;

 

整体代码:

int numDistinct(string s, string t) {
	int m = s.size();
	int n = t.size();
	if (m < n)
		return 0;
	vector<vector<long>>dp(m + 1, vector<long>(n + 1));
	for (int i = 0; i <= m; i++) {
		dp[i][0] = 1;
	}
	for (int i = 1; i < m+1; i++) {
		for (int j = 1; j < n+1; j++) {
			if (s[i-1]==t[j-1]) {
				dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
			}
			else {
				dp[i][j] = dp[i - 1][j];
			}
		}
	}
	return dp[m][n];
}

  

posted @ 2021-03-17 10:13  暮云林凌  阅读(88)  评论(0编辑  收藏  举报