leetcode 115. Distinct Subsequences 简单DP变形+一个必须要学会的DP问题
2017-09-14 13:07
405 查看
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).
Here is an example:
S = “rabbbit”, T = “rabbit”
Return 3.
题意很简答,就是类似LCS等等问题的一个DP问题。
这个问题是典型的DP解法,类似LCS 最长子序列的解法,定义二维数组dp[i][j]为字符串s(0,i)变换到t(0,j)的变换方法。如果S[i]==T[j],那么dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。意思是:如果当前S[i]==T[j],那么当前这个字母即可以保留也可以抛弃,所以变换方法等于保留这个字母的变换方法加上不用这个字母的变换方法。如果S[i]!=T[i],那么dp[i][j] = dp[i-1][j],意思是如果当前字符不等,那么就只能抛弃当前这个字符。 递归公式中用到的dp[0][0] = 1,dp[i][0] = 0(把任意一个字符串变换为一个空串只有一个方法)
代码如下:
下面是C++的做法,当你遇到字符串的匹配问题的时候就该自然而然的想到使用DP动态规划来解决,
下面就是DP动态规划来解决,
代码如下:
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.
题意很简答,就是类似LCS等等问题的一个DP问题。
这个问题是典型的DP解法,类似LCS 最长子序列的解法,定义二维数组dp[i][j]为字符串s(0,i)变换到t(0,j)的变换方法。如果S[i]==T[j],那么dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。意思是:如果当前S[i]==T[j],那么当前这个字母即可以保留也可以抛弃,所以变换方法等于保留这个字母的变换方法加上不用这个字母的变换方法。如果S[i]!=T[i],那么dp[i][j] = dp[i-1][j],意思是如果当前字符不等,那么就只能抛弃当前这个字符。 递归公式中用到的dp[0][0] = 1,dp[i][0] = 0(把任意一个字符串变换为一个空串只有一个方法)
代码如下:
/* * 这个问题是典型的DP解法,类似LCS 最长子序列的解法 * 定义二维数组dp[i][j]为字符串s(0,i)变换到t(0,j)的变换方法。 * * 如果S[i]==T[j],那么dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。 * 意思是:如果当前S[i]==T[j],那么当前这个字母即可以保留也可以抛弃, * 所以变换方法等于保留这个字母的变换方法加上不用这个字母的变换方法。 * * 如果S[i]!=T[i],那么dp[i][j] = dp[i-1][j],意思是如果当前字符不等,那么就只能抛弃当前这个字符。 * * 递归公式中用到的dp[0][0] = 1,dp[i][0] = 0(把任意一个字符串变换为一个空串只有一个方法) * */ public class Solution { public int numDistinct(String s, String t) { if( s == null || t == null || s.length() < t.length()) return 0; int dp[][] = new int [s.length()+1][t.length()+1]; dp[0][0]=1; for(int i=1;i<s.length()+1;i++) dp[i][0] = 1; for(int i=1;i<t.length()+1;i++) dp[0][i] = 0; for(int i=1;i<dp.length;i++) { for(int j=1;j<dp[0].length;j++) { if(s.charAt(i-1) == t.charAt(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.length()][t.length()]; } }
下面是C++的做法,当你遇到字符串的匹配问题的时候就该自然而然的想到使用DP动态规划来解决,
下面就是DP动态规划来解决,
代码如下:
#include <iostream> #include <string> #include <vector> using namespace std; class Solution { public: int numDistinct(string s, string t) { vector<vector<int>> dp(s.length() + 1, vector<int>(t.length() + 1, 0)); dp[0][0] = 1; for (int i = 1; i <= s.length(); i++) dp[i][0] = 1; for (int i = 1; i <= t.length(); i++) dp[0][i] = 0; for (int i = 1; i <= s.length(); i++) { for (int j = 1; j <= t.length(); 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.length()][t.length()]; } };
相关文章推荐
- LeetCode-Decode Ways-编码方式-简单DP计数问题
- leetcode 438. Find All Anagrams in a String 一个简单的移动窗口问题
- LeetCode | 746. Min Cost Climbing Stairs | 简单DP上楼梯问题
- leetcode 174. Dungeon Game 一个逆着推导计算的DP动态规划问题
- leetcode 455. Assign Cookies 饼干满足问题 + 一个简单的归并过程
- leetcode 238. Product of Array Except Self 一个动态规划DP的简单应用
- 项目中一个简单SQL查询问题,已经解决了,留个纪念,非常感谢帮我的朋友们。
- 一个看似简单却复杂的问题:求两个字符串的 左向右匹配 所有的 最长连续的 公共子字符串( 在每个字符串中先后次序相同的) 序列
- 一个简单的怪问题
- 郁闷的跨域名问题(一个简单的高校bbs十大聚合页)
- 一个简单的怪问题
- 一个简单的怪问题
- 一个数独问题的算法(已更新,提供一个简单算法,欢迎拍砖)
- 今天调试一个WebPart的简单程序出现的问题
- 今日问题:操作必须使用一个可更新的查询。
- 一个简单的问题
- 使用一个简单的webframe来解决EAI和分工合作问题
- 一个简单的初始化问题
- 如何解决ADO.NET访问Access数据库出现"操作必须使用一个可更新的查询"的问题
- 一个简单的怪问题