1.字符串的最长公共字串(string s,string t)
dp[i][j] = (s[i] == s[j] ? dp[i-1][j-1] + 1:0);
2.字符串的最长公共子序列
dp[i][j] = (s[i]==s[j]?dp[i-1][j-1]+1:max(dp[i-1][j],dp[i][j-1]))
3.求s中和t一样的子序列的个数 (leetcode115 Distinct Subsequences)
dp[i][j] = dp[i-1][j] + (s[i]==s[j]?dp[i-1][j-1]:0)
class Solution {
public:
int numDistinct(string s, string t) {
int len1 = s.length();
int len2 = t.length();
vector<vector<int>> dp(len1+1,vector<int>(len2+1,0));
for (int i=0;i<=len1;i++) dp[i][0] = 1;
for (int i=1;i<=len1;i++)
{
for(int j=1;j<=len2;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[len1][len2];
}
};
4.最长上升子序列(LIS)
方法1:普通dp O(n^2)
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n,1);
int ans = 0;
for(int i=0;i<n;i++)
{
for(int j=i;j>=0;j--)
{
if(nums[i]>nums[j])
{
dp[i]=max(dp[i],dp[j]+1);
}
}
}
for(int i=0;i<n;i++)
{
ans = ans<dp[i]?dp[i]:ans;
}
return ans;
}
};
方法2:二分查找+贪心
(待补充)
5.最长上升子序列的数量 leetcode673 Number of Longest Increasing Subsequence
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n,1),lens(n,1); //dp记录i结尾的最长上升子序列长度,lens记录i结尾的最长长度上升子序列的数量
int maxlen = 1;
for(int i=1;i<n;i++)
{
for(int j=i;j>=0;j--)
{
if(nums[i]>nums[j]&&dp[j]+1>dp[i])
{
dp[i] = dp[j] + 1;
lens[i] = lens[j];
}
else if(nums[i]>nums[j]&&dp[i]==dp[j]+1)
{
lens[i] = lens[i] + lens[j];
}
}
maxlen = max(maxlen,dp[i]);
}
int ans = 0;
for(int i=0;i<n;i++)
{
if(dp[i]==maxlen) ans+=lens[i];
}
return ans;
}
};
6.最长摇摆子序列 376. Wiggle Subsequence
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int n = nums.size();
if(n==0) return 0;
int flag = -1,maxlen = 1,pre=0;
pre = nums[0];
for(int i=0;i<n;i++)
{
if(nums[i]==pre) continue;
if(flag != nums[i]>pre)
{
flag = nums[i] > pre;
maxlen++;
}
pre = nums[i];
}
return maxlen;
}
};
7.730. Count Different Palindromic Subsequences
8.128. Longest Consecutive Sequence