【LeetCode】Distinct Subsequences

17 篇文章 0 订阅
11 篇文章 0 订阅

参考链接

http://blog.csdn.net/xshalk/article/details/8223120

http://blog.csdn.net/bigapplestar/article/details/17523391

http://blog.csdn.net/jellyyin/article/details/9060709

题目描述

Distinct Subsequences

 

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.


题目分析

题意:

给定2个字符串a, b,求b在a中出现的次数。要求可以是不连续的,但是b在a中的顺序必须和b以前的一致。

示例说明:
S =  "rabbbit"T =  "rabbit"
为了区分3个b,我们写作b0b1b3
T在S中出现了3分。分别是rab0b1it,rab0b2it,rab1b2it


思路:动态规划的关键就是找递归公式。

类似于数字分解的题目。dp[i][j]表示:b的前j个字符在a的前i个字符中出现的次数。

如果a[i] == b[j]则 dp[i][j] = dp[i-1][j] + dp[i-1][j-1]

如果a[i] != b[j]则 dp[i][j] = dp[i-1][j]


总结

这个一个典型的动态规划题,需要多多复习。

代码示例

#include 
    
    
     
     
#include 
     
     
      
      
using namespace std;
void printvec(vector
      
      
       
        A)
{
	for(int i = 0;i
       
       
        
         > A, char *name)
{
	printf("%s\n",name);
	for(int i = 0;i
        
        
          > num(S.size()+1,vector 
         
           (T.size()+1)); for(int i = 0; i<=S.size(); i++){ num[i][0] = 0; } for(int j=0; j<=T.size(); j++){ num[0][j] = 0; } for(int i = 1; i<=S.size(); i++){ for(int j = 1; j<=i && j<=T.size(); j++){ num[i][j] = num[i-1][j]; if(S[i-1] == T[j-1]){ if(j == 1){ num[i][j] += 1; }else{ num[i][j] += num[i-1][j-1]; } } } } //printvecvec(num,"ret"); return num[S.size()][T.size()]; } }; #elif 1 class Solution { public: int numDistinct(string S, string T) { // Start typing your C/C++ solution below // DO NOT write int main() function int len_s = S.size(); int len_t = T.size(); vector 
           
           
             > f(len_s+1,vector 
            
              (len_t+1)); if(len_s < len_t) return 0; for(int i = 0 ; i <= len_s ; i++) f[i][0] = 0; for(int j = 0 ; j <= len_t ; j++) f[0][j] = 0; for(int i = 1 ; i <= len_s ;i++) if(S[i-1]==T[0]) f[i][1] = f[i-1][1] + 1; else f[i][1] = f[i-1][1]; for(int i = 2; i <= len_s ; i++) for(int j = 2; j <= len_t ; j++) if(S[i-1]==T[j-1]) f[i][j] = f[i-1][j-1] + f[i-1][j]; else f[i][j] = f[i-1][j]; return f[len_s][len_t]; } }; #endif void test0() { Solution so; if(so.numDistinct("rabbbit","rabbit") != 3) printf("------------------------failed\n"); else printf("------------------------passed\n"); } int main(int argc, char *argv[]) { test0(); return 0; } 
             
            
           
          
        
       
       
      
      
     
     
    
    

推荐学习C++的资料

C++标准函数库
在线C++API查询


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值