[LeeCode] Distinct Subsequences解法

题目

Given a string S and a string T, count the number of distinct subsequences of S which equals T.A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

具体例子见原题。

分析

肯定又是动态规划 。标准套路是构建dp数组,初始化第一行和第一列,找出递推公式。但是不同的题目对应着不同的递推公式,第一次见到一种题型很难直接找到递推公式,所以只能积累,或者:自己先手动完成一个dp数组然后找规律。

该题目的例子是Input: S = "rabbbit", T = "rabbit" Output: 3,在此基础上构建的dp数组如下:

  Ø r a b b b i t
Ø 1 1 1 1 1 1 1 1
r 0 1 1 1 1 1 1 1
a 0 0 1 1 1 1 1 1
b 0 0 0 1 2 3 3 3
b 0 0 0 0 1 3 3 3
i 0 0 0 0 0 0 3 3
t 0 0 0 0 0 0 0 3

如果t的长度大于s的长度,那必然是0.然后如果t的长度为0的话,那必然是1.因为空串也算作一个子串。

我们通过观察上面的二维数组可以发现,当更新到dp[i][j]时,dp[i][j] >= dp[i][j - 1] 总是成立,再进一步观察发现,当 t[i - 1] == s[j - 1] 时,dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1],若不等, dp[i][j] = dp[i][j - 1],所以,综合以上,递推式为:

dp[i][j] = dp[i][j - 1] + (s[i - 1] == t[j - 1] ? dp[i - 1][j - 1] : 0)

我花了一段时间区试图理解这个规律背后的含义,但是想了半天感觉还是有点乱。动态规划最根本的部分无非就是递推公式,但是这个递推不是随随便便就能推出来的,所以最好的解决方式还是多做题多积累。

代码

class Solution {
public:
    int numDistinct(string s, string t) {
        int row = t.size();
        int col = s.size();
        int dp[row+1][col+1] = {0};
        for(int i=0;i<=col;i++) dp[0][i] = 1;
        for(int i=1;i<=row;i++) dp[i][0] = 0;
        for(int i=1;i<=row;i++)
            for(int j=1;j<=col;j++)
            {
                dp[i][j] = dp[i][j - 1] + (t[i - 1] == s[j - 1] ? dp[i - 1][j - 1] : 0);
            }
        return dp[row][col];
    }
};

 

猜你喜欢

转载自blog.csdn.net/qq_36303832/article/details/82821159
今日推荐