【Distinct Subsequences】cpp
2015-06-04 20:22
537 查看
题目:
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,
Here is an example:
S =
Return
代码:
tips:
这个题目第一次想到的办法是递归:统计一共要删除多少个字符;每层递归删除一个字符;扫描所有情况。 这种递归的解法大集合肯定会超时。
憋了一会儿dp的解法,这次又把问题想简单了。
这种字符串比较的题目,涉及到记忆化搜索的,可以用二维dp来做。
dp[i][j] 表示T[0:i-1]与S[0:j-1]的匹配次数。
1. 初始化过程,dp[0][i]代表T为空字符,则S若要匹配上T只有把所有字符都删除了一种情况。
2. 状态转移方程:dp[i][j]如何求解?
这里的讨论点其实很直观,即S[j-1]这个元素到底是不是必须删除。
a) 如果T[i-1]!=S[j-1],则S[j-1]必须得删除(因为这是最后一个元素,不删肯定对不上T[i-1]); 因此 dp[i][j] = dp[i][j-1],跟S少用一个字符匹配的情况是一样的。
b) 如果T[i-1]==S[j-1],则S[j-1]可删可不删;因此dp[i][j] = dp[i][j-1] + dp[i-1][j-1]:
“dp[i][j-1]”是把S[j-1]删了的情况;“dp[i-1][j-1]”是不删除S[j-1]的情况,即用S[j-1]匹配上T[i-1]
按照上述的分析过程,可以写出来DP过程。完毕。
===========================================
第二次过这道题,没想出来思路,照着之前的思路写的。
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.
代码:
class Solution { public: int numDistinct(string s, string t) { const int len_s = s.size(); const int len_t = t.size(); if ( len_s<len_t ) return 0; if ( len_s==len_t ) return s==t; vector<vector<int> > dp(len_t+1,vector<int>(len_s+1,0)); // initialization dp[0][0] = 1; for ( int i=1; i<=len_s; ++i ) dp[0][i] = 1; // dp process for ( int i=1; i<=len_t; ++i ) { for ( int j=1; j<=len_s; ++j ) { if ( t[i-1]!=s[j-1] ) { dp[i][j] = dp[i][j-1]; } else { dp[i][j] = dp[i][j-1] + dp[i-1][j-1]; } } } return dp[len_t][len_s]; } };
tips:
这个题目第一次想到的办法是递归:统计一共要删除多少个字符;每层递归删除一个字符;扫描所有情况。 这种递归的解法大集合肯定会超时。
憋了一会儿dp的解法,这次又把问题想简单了。
这种字符串比较的题目,涉及到记忆化搜索的,可以用二维dp来做。
dp[i][j] 表示T[0:i-1]与S[0:j-1]的匹配次数。
1. 初始化过程,dp[0][i]代表T为空字符,则S若要匹配上T只有把所有字符都删除了一种情况。
2. 状态转移方程:dp[i][j]如何求解?
这里的讨论点其实很直观,即S[j-1]这个元素到底是不是必须删除。
a) 如果T[i-1]!=S[j-1],则S[j-1]必须得删除(因为这是最后一个元素,不删肯定对不上T[i-1]); 因此 dp[i][j] = dp[i][j-1],跟S少用一个字符匹配的情况是一样的。
b) 如果T[i-1]==S[j-1],则S[j-1]可删可不删;因此dp[i][j] = dp[i][j-1] + dp[i-1][j-1]:
“dp[i][j-1]”是把S[j-1]删了的情况;“dp[i-1][j-1]”是不删除S[j-1]的情况,即用S[j-1]匹配上T[i-1]
按照上述的分析过程,可以写出来DP过程。完毕。
===========================================
第二次过这道题,没想出来思路,照着之前的思路写的。
class Solution { public: int numDistinct(string s, string t) { int dp[s.size()+1][t.size()+1]; fill_n(&dp[0][0], (s.size()+1)*(t.size()+1), 0); dp[0][0] = 1; for ( int i=1; i<=s.size(); ++i ) dp[i][0] = 1; // dp process for ( int i=1; i<=s.size(); ++i ) { for ( int j=1; j<=t.size(); ++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[s.size()][t.size()]; } };
相关文章推荐
- HDU 4584 Building bridges
- Arduino学习笔记之Arduino的数字输出&串口输入
- UITableView_4cell简单练习,汽车品牌展示
- UIAlertView的基本使用和对话框中按钮的事件处理方法
- 多线程NSInvocation+队列NSOperationQueue+NSBlockOperation
- likely(x)与unlikely(x)函数,即__builtin_expect的使用(转)
- 浅谈UitextField值变化的实时监视
- Codeforces 484B Maximum Value(排序+二分)
- [D3] 11. Basic D3 chart interactivity on(), select(this), classed(class, trueorfalse)
- Druid是什么
- Druid使用ConfigFilter
- 开发中使用到UITableView的各个技术点
- 如何在storyBoard中实现UIimageView长宽相等
- Java序列化中的serialVersionUID有什么用?
- iOS valueForKeyPath使用与感悟
- UITableView使用详解
- Reveal:分析iOS UI的利器
- UITableView_1简单使用
- MUI - 解决动态列表页图片懒加载再次加载不成功的bug
- UITableView优化