关闭

【Leetcode】Distinct Subsequences

标签: dp动态规划leetcode字符串子串
404人阅读 评论(0) 收藏 举报
分类:

Given a string S and a string T, count the number of distinct subsequences of T in S.

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).

Here is an example:
S = "rabbbit"T = "rabbit"

Return 3.

题意:给你一个字符串S和一个字符串T,计算S中存在多少个不同的子串和T相同,其中子串的定义是去除S中的0个以上字符后得到的字符串。

一开始想到的解法是按顺序比较,每当S的当前字符与T的字符相同,则分别向后继续寻找,直到S为空,则说明不存在子串与T相同,否则T为空,表明存在。但是时间复杂度过大,超时了,以下是超时的代码。

class Solution {
public:
    int numDistinct(string S, string T) {
        return count(S,T,0,0);
    }
    
    int count(string s,string t,int pos1,int pos2)
    {
        if(pos2==t.size())
            return 1;
        if(pos1==s.size())
            return 0;
        int sum=0;
        for(unsigned int i=pos1;i<s.size();i++)
        {
            if(s[i]==t[pos2])
            {
                sum+=count(s,t,i+1,pos2+1);
            }
        }
        return sum;
    }
};

后来对这个过程进行了仔细的分析,觉得对于类似的两个字符串问题,应该都能向动态规划方向找规律,于是思考了一下,得到了以下的规律。

1)设母串长度为i,子串长度为j,当s[i]==t[j]时,则dp[i][j]=dp[i-1][j]+dp[i-1][j-1]。当s[i]!=t[j]时,dp[i][j]=dp[i-1][j]。

2)设母串子串的长度分别为a,b。则dp的数组大小应该是(a+1)*(b+1),其中包括空字符串“”的情况。

3)数组中的dp[i][j]实际上比较的是s[i-1]与t[j-1]是否相等的情况。

4)需将dp的第一列数字置1,除dp[0][0]外的第一行置0.

以下是源代码:

class Solution {
public:
    int numDistinct(string S, string T) {
        return count2(S,T);
    }
    
    int count2(string s,string t)
    {
    	unsigned int a=s.size(),b=t.size();
    	int **dp=new int*[a+1];
    	for(unsigned int i=0;i<=a;i++)
    	{
    		dp[i]=new int[b+1];
    		memset(dp[i],0,b+1);
    	}
    	for(unsigned int i=0;i<=a;i++)
    	{
    		dp[i][0]=1;
    	}
    	for(unsigned int i=1;i<=b;i++)
    	{
    		dp[0][i]=0;
    	}
    	for(unsigned int i=1;i<=a;i++)
    	{
    		for(unsigned int j=1;j<=b;j++)
    		{
    			if(s[i-1]==t[j-1])
    			{
    				dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
    			}
    			else
    			{
    				dp[i][j]=dp[i-1][j];
    			}
    		}
    	}
    	return dp[a][b];
    }
};


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:58518次
    • 积分:1265
    • 等级:
    • 排名:千里之外
    • 原创:66篇
    • 转载:14篇
    • 译文:0篇
    • 评论:2条
    博客专栏